パスワードベースのログインでのパスワード処理に一方向関数(BCryptなど)を使用することは、一般的なアプローチです。
アプリケーションがユーザーのパスワードから導出されたキーを使用して秘密キーを暗号化する場合、ログイン時に成功した復号化に依存しても安全ですか?
例:
登録(クライアント側で実行されるすべての手順):
ログイン(クライアント側で実行されるすべての手順):
はい、これは実行可能なアプローチですwhen指定したように、認証された暗号化を使用します。暗号化されたデータの認証タグは、保存されたパスワードハッシュに似ており、GCMはメッセージの偽造を防ぐように特別に設計されています(つまり、秘密鍵にアクセスせずに構築された有効なタグ)。
実際、GMACはGCMモードのバリアントであり、データを暗号化しないように設計されていますが、一部のデータに対して共有キーで署名を提供するためにjustを使用しています。
これは、認証されていない暗号では行わないでください。「正しい」復号化を検出するためにパディングが使用されている場合でも、これにより、(不正なキーであるにもかかわらず、正しいパディング。
これはすべて言われていますが、これはgoodの考えではないと思います。これは、標準のパスワードストレージスキームよりも実装エラーが発生しやすいためです。このスキームを攻撃することは、十分に研究された認証メカニズムであるユーザーパスワードの別のPBKDF2ハッシュを攻撃することと同じくらい簡単/困難です。 2つのPBKDF2ハッシュの計算でCPU時間を心配している場合は、以下を実行できます。
key = PBKDF2(Password, Salt, N)
を計算します。pwhash = PBKDF2(Password, Salt, N+1)
を計算して、保存されているパスワードハッシュを導出します。 (これは、上記の元のハッシュで1つの余分なラウンドのみで実行できます。)PBKDF2(Password, Salt, N+1)
をPBKDF2(Password, Salt, N)
に反転することは、使用するハッシュ関数でHMAC
を反転することと同じです。
上記のスキームは、Lastpassが認証とパスワードボールトの復号化に使用するスキームです。 (pwhash
のみがサーバーに送信されるため、パスワードボールトのキーをそこから回復することはできません。)