web-dev-qa-db-ja.com

データベースにBcryptハッシュパスワードを保存するためにどのカラムタイプ/長さを使用すべきですか?

ハッシュされたパスワードを(BCryptを使って)データベースに保存したいのですが。これに適したタイプは何でしょうか。正しい長さはどれでしょうか。パスワードは常に同じ長さのBCryptでハッシュされますか?

EDIT

ハッシュの例

$2a$10$KssILxWNR6k62B7yiX0GAe2Q7wwHlrzhF3LqtVvpyvHZf0MwvNfVu

いくつかのパスワードをハッシュした後、BCryptは常に60文字のハッシュを生成するようです。

編集2

実装について言及していないため申し訳ありません。私は jBCrypt を使っています。

276
helpermethod

Bcryptのモジュラー暗号化形式は、

  • $2$$2a$、または$2y$は、 ハッシュアルゴリズムと形式を識別します
  • コストパラメータを示す2桁の値とそれに続く$
  • 53文字のbase-64エンコード値(アルファベット./09AZを使用します、azは、以下で構成される 標準のBase 64エンコード アルファベットとは異なります。
    • 22文字のソルト(実質的にデコードされた132ビットのうち128ビットのみ)
    • 暗号化された出力の31文字(事実上、デコードされた186ビットのうち184ビットのみ)

したがって、合計の長さはそれぞれ59バイトまたは60バイトです。

2a形式を使用する場合、60バイトが必要です。したがって、MySQLの場合、 CHAR(60) BINARYまたはBINARY(60) を使用することをお勧めします( を参照)_ binおよびbinary照合順序 の違いについて).

CHARはバイナリセーフではなく、等価性はバイト値だけでなく実際の照合に依存します。最悪の場合、Aaと等しいものとして扱われます。詳細については、 The _binおよびbinary照合を参照してください

339
Gumbo

BcryptハッシュはBINARY(40)列に格納できます。

BINARY(60)は、他の答えが示すように、最も簡単で自然な選択ですが、ストレージ効率を最大化したい場合は、ハッシュを無損失に分解することで20バイト節約できます。私はこれをGitHubでもっと徹底的に文書化しました: https://github.com/ademarre/binary-mcf

Bcryptハッシュは、モジュラー暗号フォーマット(MCF)と呼ばれる構造に従います。 バイナリMCF(BMCF)は、これらのテキストハッシュ表現をよりコンパクトなバイナリ構造にデコードします。 Bcryptの場合、結果のバイナリハッシュは40バイトです。

Gumboは、Bcrypt MCFハッシュの4つの要素を説明するためにNiceの仕事をしました。

$<id>$<cost>$<salt><digest>

BMCFへのデコードは次のようになります。

  1. $<id>$は3ビットで表すことができます。
  2. 04-31の<cost>$は5ビットで表すことができます。これらを1バイトにまとめます。
  3. 22文字のsaltは128ビットの(標準ではない)base-64表現です。 Base-64デコードでは16バイトになります。
  4. 31文字のハッシュダイジェストは、64バイトで23バイトにデコードできます。
  5. 全部で40バイトにまとめてください:1 + 16 + 23

あなたは上記のリンクでもっと読むか、あるいはGitHubで my PHP implementation を調べることができます。

48
Andre D

あなたがPHPの password_hash()PASSWORD_DEFAULTアルゴリズムと共に使ってbcryptハッシュを生成する場合(これはこの質問を読んでいる人の大部分が想定しています)、将来password_hash()が使用するかもしれないことを忘れないでください。デフォルトとは異なるアルゴリズムであり、これはハッシュの長さに影響を与える可能性があります(ただし、必ずしも長くなるとは限りません)。

マニュアルページから:

この定数は、新しい強力なアルゴリズムがPHPに追加されたときに時間の経過とともに変化するように設計されています。そのため、このIDを使用した結果の長さは時間の経過とともに変わる可能性があります。したがって、結果を60文字を超えて拡張できるデータベース列に格納することをお勧めします(255文字が良い選択でしょう)。

255バイトのパスワードハッシュを保存するために10億人のユーザーがいる場合でも(つまり現在Facebookと競合している場合でも)、bcryptを使用すると、約255 GBのデータしかないことになります。パスワードハッシュを保存することがアプリケーションのボトルネックになることはほとんどありません。ただし、何らかの理由で実際にストレージスペースが問題になる可能性があるので、PASSWORD_BCRYPTを使用してpassword_hash()にbcryptを使用させることができます。デフォルト。新しいPHPバージョンがリリースされるたびに、bcryptに見つかった脆弱性について常に最新の情報を入手し、リリースノートを確認するようにしてください。デフォルトのアルゴリズムが変更されたことがある場合は、その理由を確認し、新しいアルゴリズムを使用するかどうかについて十分な情報に基づいて決定することをお勧めします。

21
Mike

たとえばMD5ハッシュでできることのように、これを保存するためにできる巧妙なトリックはないと思います。

私はあなたの最善の策はそれが常に60文字の長さであるのでCHAR(60)としてそれを保存することであると思います

18
James C