パスワードとかをメールで安心して受け取るための暗号ボックス 🆓
Web Crypto APIを使って、カジュアルにRSA暗号を使う無料ツールをリリースしました。
暗号関係は正直知識や経験が浅く、この実装でいいのかな?と思うところもあるので、詳しい方がいらしたらぜひアドバイスください!
なぜ作ったか
PPAPも然りパスワードとかをメールで送られるとドキッとするのでなんとかしたいと思いつつ、暗号化は何かと敷居が高いのでカジュアルに使える自分ツールが欲しいと考えていました。
調べていたらWeb Crypto APIの存在を知り、これならブラウザだけのオフラインでRSAをサクッと使えるんじゃない?と思い、2月の3連休でガガっと作った次第です。
方向性
とっつきやすくする
暗号化をして欲しい相手が暗号に詳しいことはまずないので、できるだけ専門用語を使わず使ってもらえるようにしたいです。
僕もBase64を見ると酔ってしまうので、公開鍵の表現にこのとてもかわいいボックス状のIdenticonを拝借しました。
この箱に情報を入れると暗号にできて、箱の持ち主しか解読できないんだよという説明だとちょっとわかりやすいかなーと思いました。
サーバーを持たない
平文や秘密鍵をネットワークに通したくないので、すべてブラウザ上のJavaScriptで完結します。
今はFirebaseでホスティングしていますが、Webサーバーさえあればどこでも運用できます。
暗号処理の実装について
キーペアの生成と保存
初回アクセス時にRSA-OAEP
のキーペアを生成します。以下のサンプル通りです。
公開鍵はSPKI
でエクスポートしてLocalStorageに保存します。
秘密鍵はそのままエクスポートしてLocalStorageに保存すると、XSSが成立したときに抜かれちゃってヤバいのでユーザーの決めたあいことば
でAES暗号にします。
あいことば
にしたのは、このツール自体がパスワードとかを暗号化するツールなので、混同しないように言葉を変えてみたわけです。
そのためのwrapKey
というAPIがあるので、これもほぼサンプルのまま使います。変えたのはソルトを128ビットにしたことくらいです(長い方がいいらしいので)。
初期化ベクトルIV
とソルトは秘密鍵を複合するときに使うので、LocalStorageに保存しておきます。
IV
は秘匿する必要なさそうなんですが、ソルトを平文で同じ場所に置くのはあまり良くないんじゃないかなと思いつつ、他にいい方法が思いつきませんでした。ソルトを長くしてもこれでは意味なさげ…
暗号化
公開鍵をそのままURLとした暗号化フォームを一般に公開します。
URLがめっちゃ長い…
平文を公開鍵でRSA-OAEP
により暗号化します。これもほぼサンプル通り。
復号
wrapKey
で暗号化した秘密鍵を、IV
とソルトとともにunwrapKey
でメモリ上だけに復元します。
その秘密鍵を使って上記で作った暗号を復号します。
こんな感じで、平文や鍵をネットワークに通すことなく、オフラインで暗号を処理します。
ぜひ試してみてください!
組織的・設備的に脅威への対策ができているなら、このツールは特に必要ないでしょう。
メールや汎用的なツールで仕事をしているけど、セキュリティには少し気を遣いたい、という方に使ってもらえると嬉しいです。