web-dev-qa-db-ja.com

node.js scrypt関数がHMACをこのように使用するのはなぜですか?

ドキュメント によると、scryptハッシュ関数は次のように機能します。

ハッシュ関数は次のことを行います。

  • ランダムな塩を追加します。
  • アクティブな攻撃から保護するためのHMACを作成します。
  • Scrypt鍵導出関数を使用して、鍵のハッシュを導出します。

ハッシュ形式

すべてのハッシュは「scrypt」という単語で始まります。次に、鍵導出関数で使用されるscryptパラメータが続き、ランダムなソルトが続きます。最後に、以前のコンテンツの256ビットHMACが追加され、HMACの鍵が暗号鍵導出関数によって生成されます。結果は768ビット(96バイト)の出力です。

  1. バイト0-5:ワード「scrypt」
  2. バイト6から15:ScryptパラメーターN、r、およびp
  3. バイト16〜47:32ビットのランダムソルト
  4. バイト48〜63:16ビットのチェックサム
  5. バイト64-95:暗号鍵導出関数によって生成された鍵を使用するバイト0から63の32ビットHMAC。

バイト0から63は平文のままです。これらのバイトにはハッシュの検証に必要なメタデータが含まれているため、これは必要です。この情報が暗号化されていなくても、セキュリティが低下しているわけではありません。セキュリティの観点から重要なのは、ハッシュの整合性(ハッシュされた出力のどの部分も変更できないこと)と、ハッシュされた出力から元のパスワードを特定できないことです(これがscryptを使用している理由です-これは良い方法)。バイト64〜95は、これがすべて発生する場所です。

私の質問は、scryptハッシュを直接返すのではなく、scryptハッシュをHMACアルゴリズムのキーとして使用するのはなぜですか?これはどのような追加の保護を提供しますか? 「能動的攻撃」について言及しているが、詳細については触れていない。

8
ChrisD

Node Scryptモジュールを作成しました。

HMACはセキュリティを強化します。これを使用すると、認証サーバーのデータベースだけでなく、(tarsnapで行われるように)暗号化されたファイル形式のヘッダーとして使用されるスキームも貸し出されます。また、Colin Percival(scryptを作成した人)はこのスキームを使用して検証します(実際には彼からコピーしただけです)。

HMACが使用される理由を説明するために、簡単にまとめます。暗号鍵導出関数を使用して何かを暗号化すると、96バイトの結果が生成され、次のように分解されます。

 bytes 0-5: The Word "scrypt"
 byte 6: 0
 byte 7: logN
 bytes 8-11: r
 bytes 12-15: p
 bytes 16-47: salt (which is 32 bytes)
 bytes 48-63: A 16 byte SHA256 checksum (hash) of the contents of bytes 0 to 47
 bytes 64-95: A 32 byte HMAC hash of bytes 0 to 63 with the key being the scrypt cryptographic hash

バイト0から47は平文であることが重要です(いかなる方法でも変更または暗号化されていません)。これを確実にするために、16バイトのSHA256チェックサムがあります。 SHAはチェックサムとして非常に効果的に使用できますが(特にこの場合))、アクティブな攻撃から保護することはできません。つまり、誰かがペイロードを入手し、独自の値に置き換えました。たとえば、ペイロードを取得し、自分のlogN、r、pと自分のチェックサムを計算して、それを元の値として渡すことができます。

これを防ぐために、最後の32バイトはHMACです。 HMACはメッセージの整合性を保証するために使用され(つまり、ペイロードを積極的に変更する人から保護します)、暗号化兵器の主力です(読み取り:安全に使用できます)。 HMACには鍵が必要であり、scryptハッシュを鍵として使用します。

最後の32バイトが単なるscryptハッシュである場合、アクティブな攻撃者がすべてを危険にさらして自分のscryptハッシュを代用することを妨げるものはありません。 HMACはこれを防ぎます。これは、scryptハッシュを検証する手段としてだけでなく、スキーム全体の整合性もチェックします。

ところで、チェックサム(バイト48から63)が必要な理由を不思議に思う人もいるかもしれません。まあ、あなたがそれについて考えるなら、私たちはscryptハッシュを計算して、HMACのキーとして使用できるようにする必要があります。したがって、チェックサムは追加のレベルのチェックを追加します。それがパンしない場合、検証はそれ以上続行せずにすぐにfalseを返します。

17
Barry Steyn

これについては、後で説明します。

このモジュールに興味があり、パスワードを格納するためのハッシュを生成する場合は、ハッシュ関数を使用することを強くお勧めします。鍵導出関数は、完全性を保証するためのメッセージ認証コードを生成しません。また、scryptパラメータを個別に保存する必要があります。最後に、このモジュールにはネイティブの検証機能は含まれていません。

必要なのは、scryptアルゴリズムを使用してキーを取得することだけである場合は、このパッケージに含まれている KDF function を使用して取得できます。

このパッケージのいわゆるハッシュ関数は、元のscryptハッシュ関数のラッパーです。

2
aviv