web-dev-qa-db-ja.com

ユーザー提供のパスワードと初期化ベクトルを使用したAES-256-CBCの安全性

私の理解では、IVは最初のブロックの前のブロックとしてのみ使用されます。しかし、各ブロックは以下で使用されるため、これは重要なセキュリティを追加します。IVが提供され、パスワードに基づいていません。

したがって、私はユーザーが両方を提供するときにログインシステムを実装しました。少なくとも3つのタイプ(上、下、数値、特殊、非ASCII)を使用する限り、ユーザーが気にする任意の文字を使用して8文字以上で区別します。

しかし、今や誰かが、IVを定義することで暗号化を弱めるとパスワードがある程度役に立たなくなると私に言った。

私は彼の説明を正確に理解していませんでした。

私のコードは次のようになります:

$hash = openssl_encrypt($username, 'aes-256-cbc', $password, false, md5($iv, true));
  • はい、ユーザー名を暗号化しています
  • パスワードとIVの両方がユーザー定義です
  • はい、2つのパスワードを求めています
  • IVをRAW md5でラップして、標準の16 chの長さを取得できるようにします

この方法でのIVの使用が適切であり、このアイデアが十分強力であるかどうかを誰かが明確にできますか?.

4
transilvlad

私の疑いは次のとおりです: あなたはそれを間違っています™

これが、頭の上からそう思う理由です。

  1. 暗号文を保持する変数はhashと呼ばれます。
  2. ユーザー名を暗号化しています。
  3. これは XY-Problem のようになります。
  4. パスワードからキーを導出しない(方法を示す)(openssl_encryptpasswordがドキュメントによるとキーです。したがって、ユーザーが提供したパスワードからキーを導出しない限り、それはうまくいきません。)
  5. AES-CBCのIVを取得するために CSPRNGを使用 ではありません。

しかし、今や誰かが、IVを定義することで暗号化を弱めるとパスワードがある程度役に立たなくなると私に言った。

その人は正しかった。詳細については、AES-CBCでのCSPRNGの使用に関する暗号化に関するリンクされた質問を参照してください。

20
Tobi Nary

まず、通常の警告:自分の暗号をロールバックしないでください。間違っている可能性があります。

ここで2番目の警告:AES - [〜#〜] cbc [〜#〜] のみを使用してデータを暗号化しているようです。これは非常に危険です。本当にAES - [〜 #〜] gcm [〜#〜] 、AESのCBC操作モードではメッセージの変更が妨げられず、望ましくない結果が生じる可能性があるため。

暗号化スキームの大きな問題:外部のランダム性を導入しない
CBCモードでは、unpredictable であるIVが必要です。そうでなければ、攻撃を受けやすくなります。あなたがMD5(pw2)を使用するという事実により、このIVは予測不可能ですほとんどのパスワードは予測可能になるためです。さらに悪いことに、IVは暗号化にランダム性を導入し、同じ平文を異なる暗号文に暗号化することになっています。ただし、ユーザーがそれを理解できず、パスワードのペアを複数の暗号化で再利用する可能性があるため、静的IV攻撃を受けやすい可能性があります。

別のいくつかのマイナーな問題:

  1. キーを確認していません(別名$password)は正確に32バイトの長さ(AES-256を使用するための要件)および(疑似)ランダム(セキュリティのための正式な要件)であり、ユーザーが32文字を超えるパスワードを選択すると問題が発生する可能性があります。
  2. ユーザーに2つのパスワードを要求する一方で、実際には1つのパスワードを要求して、その2つを(決定論的に)導出することができます。
  3. パスワードを処理しません 。今のところ、暗号文が漏洩した場合は、先に進んでユーザーのパスワードをブルートフォースで試すことができます。これは、パスワードの推測に対する対策( bcrypt を使用するなど)を展開していないためです。

それで、それを修正する方法は?

  1. 12バイトのナンスでAES-GCMを使用します。
  2. OpenSSLs RNGを使用して、上記のナンスを生成します。
  3. ユーザーのパスワードからAES-GCMキーを安全に取得します(bcryptまたは Argon2 を使用)。
10
SEJPM