以前書いた、「あるデータをパスフレーズで暗号化し、公開ストレージ(URLが判明すれば誰でも読み取り可能)に暗号化ファイルの形式で保存し(期間は無期限)、あとからパスフレーズで復号して読み取るためのコード」を改修するため、「AES-256 GCM、または、ChaCha20-Poly1305を用いて、データを1つのパスフレーズを用いて暗号化するライブラリ」をTypeScriptで書こうと考えています。
この場合の要件は:
- 暗号化したデータは、第三者が自由に読み取り可能であり、その場合でも安全性を保つ必要がある
- 暗号化したデータは、無期限で利用される場合がある。したがって、短期間のみ用いるものではない
- 暗号化したデータには、パスフレーズを除く、復号に必要な情報がすべて含まれる。暗号化と複合に必要な秘密情報はパスフレーズのみ
になります。例えるなら、Gitリポジトリ内で特定のファイルを暗号化するような場合や、「パスワード管理ツールが生成する暗号化データベース」のようなファイルを生成したい場合に用いるものです。
先行事例を探していたところ、以下のものを発見しました。
このパッケージは、AES-256 GCM方式で平文とパスワードを元に暗号化を行っています。しかし、パスワードを直接AES-256 GCMのkeyには指定せず、鍵導出関数のPBKDF2を使用してハッシュ化していました。この理由がわかりません。
私の理解では、AES-256 GCMの暗号化と復号には、平文以外に「256bitのkey」と「96bitのIV(Initialization Vector;初期化ベクトル)」が必要です。このうち、IVは秘密である必要はありません。したがって、keyのみが秘密情報であり、暗号文からはkeyが絶対に解析できないはずです。(でなければ暗号の意味がない)
一方、鍵導出関数はパスワード/パスフレーズのハッシュ化に用いるためのもので、私の理解では「データベースに『パスワード/パスフレーズの平文』の代わりにハッシュ値を保存し、データの漏洩時にパスワード/パスフレーズの平文を知られないようにするためのもの」です。
よって、AES-256 GCMのkeyに鍵導出関数のハッシュ値を用いる理由として考えられるのは、「keyが暗号文から読み取られた場合」のための備えであると思われます。しかし前述したように、暗号の意味が無くなる「keyが暗号文から読み取られた場合」という想定自体がありえないはずです。
そうなると、パスワード/パスフレーズを鍵導出関数でハッシュ化する理由として考えられるのは、「任意長のパスワード/パスフレーズを256bitの長さのkeyに変換」するためというものです。しかしこれなら、鍵導出関数を用いなくとも、SHA-256などで代用できるはずです。
SHA-256などを使用せず、代わりに鍵導出関数を使う理由として考えられるのは、「不適切に複数のハッシュ関数を利用すると、脆弱になる場合がある」というどこかで聞きかじった情報ですが、確証が得られていません。
まとめると、
- 鍵導出関数を使う理由は、パスフレーズ(として使われる値)が漏洩した場合の備え
- しかし、AES-256 GCMのkeyが暗号文から漏洩する可能性は考えられない
- AES-256 GCMのkeyに鍵導出関数のハッシュ値を用いる理由が不明
という疑問が生じます。
なぜ、暗号文から内容が判明しないはずのkeyに、鍵導出関数を用いたハッシュ値を指定するのでしょうか?
回答2件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2021/04/12 09:04