Web CryptoのCryptoKeyはブラウザー保存へ直列化でき、MDNはIndexedDBを代表例として挙げています。ただし保存場所だけで鍵管理が安全になるわけではありません。同一originで悪意あるコードが動けば、許可された鍵操作を要求できる可能性があります。MDN Web Crypto API、CryptoKey.extractable、WebKitの暗号解説を確認しました。Web Cryptography仕様の原文も参照し、CryptoKeyのモデルを確認します。

透明なカプセル内の鍵、内向きの3本の矢印、禁止記号で示された外向きの点線経路を描く概念イラスト

*鍵の取り出し制限を表す比喩です。許可された暗号操作やXSSの状況は示していません。*

概念図であり、ブラウザーの安全性試験ではありません。

CryptoKeyとextractableの意味

CryptoKeyは鍵を表すオブジェクトで、algorithm、usages、type、extractableを持ちます。extractable:falseはexportKeyやwrapKeyで鍵素材を取り出せない制限です。稼働中コードが許可された暗号化・復号操作を呼べないことや、保存領域の暗号化と同じではありません。機能に必要な鍵の用途だけを指定します。

IndexedDBは露出の一部を減らす

CryptoKeyは構造化複製でき、IndexedDBへ保存して読み戻せます。非extractableならその処理で生の鍵bytesをアプリへ露出しない利点があります。一方、ブラウザープロファイル侵害、同一originのXSS、弱いアカウント復旧、端末バックアップや同期などは別の脅威です。鍵の寿命とアカウント分離を設計し、保存場所を安全な金庫とみなさないでください。

wrapping keyには別の依存がある

鍵を移送する場合はwrapKeyとunwrapKeyを検討できます。wrapped keyは別の鍵で保護されますが、その鍵の生成、保存、復旧が弱ければ保護も弱くなります。データ鍵とwrapping keyを分け、アルゴリズム設定と復旧手順をレビューします。API呼び出しを組み合わせるだけで鍵管理全体が完成するわけではありません。

脅威モデルから決める

ブラウザー内の機密を守るなら、サーバーが鍵を見られるか、同じ端末のscript侵害を想定するか、logout時に何を消すか、端末間復旧を支援するかを決めます。たとえばXSSでページscriptが操作されると、鍵bytesをexportできなくても、許可された復号を要求して結果を外部へ送れる可能性があります。この経路を明示的に検討してください。extractable:falseが制限するのは鍵の取り出しであり、許可済みの使用ではありません。XSS対策、CSP、session保護、保存領域の整理も合わせて設計します。機密データでは低水準のWeb Crypto APIを組み合わせる前に全体設計をレビューしてください。

復旧と端末変更を設計する

ブラウザー保存のCryptoKeyは、データ削除、profile初期化、端末交換後に自動復旧するbackupではありません。アカウント同期で安全に移ると決めつけず、復旧鍵やserver側envelope encryptionを加える場合は誰が鍵を持ち、侵害時に何が漏れるかを考えます。復旧不要でlogout時に消すなら、IndexedDBのrecordと関連ciphertextの寿命を定義します。

raw key、wrapping key、平文の復旧情報を開発者ツールやアプリのログへ出さないでください。暗号方式、nonce管理、認証付き暗号、アカウント復旧を合わせて確認し、保存APIだけで判断しないようにします。

参考資料