web-dev-qa-db-ja.com

PBKDF2を使用したダイジェスト認証の改善

さまざまな理由から、作成したRESTサーバーにダイジェスト認証を使用する必要があります。

私は、クライアントに負担をかけることなく、MD5攻撃に対するアルゴリズムを強化する「改善」を思いつきました。私のアルゴリズムでどのような問題が見られますか?

前書き

  • クライアントは、C#で記述されたカスタムアプリケーションです。
  • サーバーはJAX-RSベースのRESTサーバーはJavaで記述され、Tomcatで実行されています。
  • クライアントとサーバー間のすべてのトラフィックは、SSL/TLSを使用して暗号化されます。
  • データベースには、次の列を持つuser_tableが含まれています。

    • user_id:主キー
    • password_hash:varcharがnullではない
    • salt:varcharがnullではない
    • iteration_count:整数

ダイジェスト認証(RFC2617)

ダイジェスト認証では、次の計算を使用します。

nonce: server-generated number used once
nonceCount: server-generated increasing value (prevents replay attacks)
cnonce: client-generated number used once
qop: quality of protection ("auth")
method: typically one of "GET", "POST", "PUT", etc.

HA1 = MD5(username:realm:password)
HA2 = MD5(method:digestURI)
response = MD5(HA1:nonce:nonceCount:cnonce:qop:HA2)

HA1値は、パスワードハッシュ値としてデータベースに格納されます。認証中に、クライアントはWWW-authenticate httpヘッダーからresponseの値を計算します。サーバーは、格納されているHA1のバージョンを使用してresponse値も計算し、クライアントから受信した値を比較します。それらが等しい場合、クライアントは認証されます。

MD5は安全とは見なされなくなりました。市販のハードウェアを使用すると、数時間で衝突が見つかります。

PBKDF2を使用してダイジェストを強化する

  • クライアントはユーザーからユーザー名とプレーンテキストのパスワードを取得します。
  • クライアントは、サーバーにuser_idのソルトと反復カウントを要求します。サーバーは、現在のデフォルトの反復回数も送信します(これは、このユーザーに使用されているものとは異なる場合があります)。
  • クライアントはPBKDF2(パスワード、ソルト、ユーザー固有の反復回数)を使用して128ビットの秘密鍵を計算します。秘密鍵は16進数の文字列としてエンコードされます。
  • クライアントは、ユーザー名、レルム、16進数でエンコードされたキーを使用してHA1を計算します。このHA1値は、標準のダイジェスト認証で使用されます。
  • サーバーはデータベースからパスワードハッシュを取得します。パスワードハッシュは、同じPBKDF2派生秘密鍵を使用して以前に計算されたHA1です。サーバーは、計算されたresponseをクライアントが送信したresponse値と比較します(標準のダイジェスト認証)。 2つのresponse値が等しい場合、クライアントは認証されます。
  • クライアントに返されるユーザー固有の反復回数がデフォルトの反復回数と異なる場合、クライアントはPBKDF2と新しい反復回数を使用して新しいHA1を計算します。クライアントは、RESTサーバー上でPUTメソッドを呼び出して、新しい値を使用してパスワードハッシュ列を更新します。この手順により、ハードウェアが取得するにつれて、アルゴリズムをより大きな反復回数で更新できますもっと早く。

パスワードハッシュの計算の難しさはPBKDF2(SHA-1またはSHA-256ハッシュを使用できる)に依存するため、変更されたアルゴリズムはパスワードハッシュを保護するためにMD5の強度に依存しません。

この変更されたアルゴリズムに明らかなセキュリティ上の欠陥はありますか?

2
Ralph

PBKDF2負担です。それがすべてのポイントです。何千回もの繰り返しにより、設計上、大量のCPUが消費されます。

それとは別に、あなたのスキームは確かにプレーンダイジェスト認証のアップグレードですが、すべてを修正するわけではありません。特に、サーバーが保存するもの(HA1 value)は「同等のパスワード」です。この値がわかっている場合は、この値を使用してサーバーに接続し、認証ゲームをプレイできます。これは、攻撃者がサーバーに侵入し、保存されている「パスワード」のコピーを盗むと、すべてのアカウントに即座にアクセスできることを意味します(つまり、攻撃者は、SQLインジェクション攻撃などにより、テーブルの部分的な読み取り専用のピークを変換します。または誤って置かれたバックアップテープ、完全な読み取り/書き込みアクセス)。それは通常悪いと考えられています。サーバーはパスワードを「そのまま」保存する必要があるため、プレーンダイジェスト認証にはすでにこの問題があります。 PBKDF2を使用しても問題は解決しません。

いずれにせよ、SSL(HTTPS)内でこのプロトコルを実行してください。そうしないと、接続が乗っ取られるだけです。また、doプロトコルをSSL内で再生する場合は、基本認証を使用できます。これにより、クライアントはさらに簡単になり、サーバーはPBKDF2を適用できます。それ自体、そしてパスワードに相当するnotである結果のハッシュを格納します。

8
Thomas Pornin