リポジトリは https://github.com/nabetani/mandihe/ 。
mandihe は、MANual DIffie-HEllman から。
手順
- Alice→Bob: 鍵交換支援HTMLを生成するHTMLへのアクセスを提供する。
- Alice→Bob: 公開鍵を伝える。
- Bob: 鍵交換支援HTMLと Alice からもらった公開鍵を使って、パスワードとダイジェストを作る。
- Bob→Alice: ダイジェストとBobの公開鍵を Alice に伝える
- Alice: Bobからもらった公開鍵で、パスワードとダイジェストを作る。手元で作られたダイジェストと Bobからもらったダイジェストが一致していることを確認する。
- Ailce→Bob: 一致しているからOKだよ、と伝える。
Alice と Bob の間の通信はすべて平文でOK。盗聴されても問題ない。
盗聴+改竄だと困ると思う。
盗聴+改竄 に耐えるようにするには認証局(のようなもの)がないと無理なんじゃないかと思っているんだけど、どうだろう。
(1) の「鍵交換支援HTMLを生成するHTMLへのアクセスを提供」は、平文で HTML を送ってもいいし、サーバーに置いて URL を伝えてもいい。
仕組み
鍵交換をメールなどを通じて行う。
鍵交換の情報の流れは下図の通り:
「鍵交換支援HTMLを生成するHTML」がある理由
鍵交換支援HTMLは、 crypto.subtle.generateKey
で鍵ペアを作る。
HTML を表示するたびに鍵ペアを作るようにすると、
2.Alice→Bob: 公開鍵を伝える。
と
5.Alice: 手元で作られたダイジェストと Bobからもらったダイジェストが一致していることを確認する。
の間に数日空いたりすると運用上面倒なことになる。
面倒を避けるために鍵ペアを記憶したい。
秘密鍵も記憶するので、暗号化したい。
暗号化には鍵が要る。
では、その鍵はどこに保存するか...という問題がある。
そこで
- 鍵は、
crypto.getRandomValues
で生成。 - 生成した鍵は「鍵交換支援HTML」内の JavaScript のソースコードに埋め込む。
という作戦にした。
これで、 localStorage
であっても安全に秘密鍵を保管することができる。
情報の流れは下図の通り:
index.html
が「鍵交換支援HTMLを生成するHTML」で、 key-exchange-helper.html
が「鍵交換支援HTML」である。
- 「鍵交換支援HTMLを生成するHTML」内でパスワードを生成
- 生成したパスワードを埋め込んだHTMLを「鍵交換支援HTMLを生成するHTML」内で生成
- 生成したHTMLを Base64 にして、
href
に入れる - リンクを右クリック→名前を付けて保存 で、できたての HTML をダウンロード
という流れになる。
パスワードの生成からダウンロードまでの流れに通信が絡まないので傍受できない。
これで、
- localStorage にデータがあればそれを表示
- なければ生成
という処理にすることができる。
これで運用上の面倒がなくなる。
動作するブラウザ
手元で調べたところ
- 最新の Firefox
- 最新の Google Chrome
- 最新の Microsoft Edge(Chromium版)
で動作することがわかった。調べたのは macOS版 と Windows版。
一方。
- 最新の Safari on macOS
- 最新の Internet Explorer 11 on Windows
では動作しない事がわかった。残念。
非 Chromium の Edge は手元にないので試していない。