base64の64は64bitから来ていることを最近知った、弓削田です。
最近localStorageにデータを格納する時に、平文の文字列ではなく、base64に変換しておくことで少しだけ安心感を感じるようになりました。
何の安心かと聞かれると、さほど大したことは無いんですが、パッと見で、データが見られないという程度の安心感です。
こうしたお作法を知らない人が、実際に使ってみると、javascriptでのbase64の扱いやすさにビックリするでしょう。
そんなjavascriptにおける、base64の扱いについて簡単にまとめてみます。
javascriptで文字列をbase64にエンコード、デコードする方法
string -> base64にエンコード
let str = "test-hogehoge";
let b64 = btoa(str);
console.log(b64);
> dGVzdC1ob2dlaG9nZQ==
base64 -> stringにデコード
let b64 = "dGVzdC1ob2dlaG9nZQ==";
let str = atob(b64);
console.log(str);
atobとbtoaだけ覚えておけば簡単に変換できますが、どっちがどっちだったのか、たまに忘れてしまうことがあります。
なんとなく、"ascii->base64"でatobがエンコードのように考えがちですが、実際は"btoa"です。
2バイト文字が入っていると、エラーが出るよ
どんな文字列もbase64に変換してくれる便利な機能ですが、エンコードする文字の中に、2バイト文字が含まれていると、エラーが表示されます。
let str = "あ";
let b64 = btoa(str);
> Uncaught DOMException: Failed to execute 'btoa' on 'Window': The string to be encoded contains characters outside of the Latin1 range.
まあまあ、たいそうなエラーが出て意味不明な感じですが、直訳すると
「「Window」で「btoa」の実行に失敗しました:エンコードされる文字列にLatin1の範囲外の文字が含まれています。
ということで、Latin1というのは「ISO 8859-1」という文字コードの略称で、ようするに2バイト文字であると理解するといいでしょう。
これを回避するために、javascriptでは、urlエンコードを使って、以下のようにすることで、簡単に変換することができます。
2バイト文字を含むstring -> base64にエンコード
let str = "あ";
let b64 = btoa(unescape(encodeURIComponent(str)));
console.log(b64);
> 44GC
2バイト文字を含む base64 ->stringにデコード
let b64 = "44GC";
let str = decodeURIComponent(escape(atob(b64)));
console.log(str);
> あ
少し複雑に見えますが、encodeURIComponentでurlで使えるバイト文字列に変換して、unescapeでエスケープ処理をしているんですね。
デコードはその逆を行っているというワケです。
セキュアではないよ
文字列をbase64データに変換すると、ひと目見ただけでは分からない文字列データになるので、暗号化なのかというと全く違います。
一般的に暗号化は、何かしらの鍵を持ってしかデコードできない状態の事をいうので、鍵無しで簡単にデコードできてしまうbase64は決してセキュアというわけではありません。
あえて言うなら「難読化」というレベルでしょう。
でもまあ、こうした技術を知らないレベルの人であれば、デコードする方法すら分からないので、ある一定のふるいはかけられそうですが、セキュアと信じてデータを扱うのは危険ということを知っておきましょう。
0 件のコメント:
コメントを投稿