ハッシュされたパスワードを(BCryptを使って)データベースに保存したいのですが。これに適したタイプは何でしょうか。正しい長さはどれでしょうか。パスワードは常に同じ長さのBCryptでハッシュされますか?
EDIT
ハッシュの例
$2a$10$KssILxWNR6k62B7yiX0GAe2Q7wwHlrzhF3LqtVvpyvHZf0MwvNfVu
いくつかのパスワードをハッシュした後、BCryptは常に60文字のハッシュを生成するようです。
編集2
実装について言及していないため申し訳ありません。私は jBCrypt を使っています。
Bcryptのモジュラー暗号化形式は、
$2$
、$2a$
、または$2y$
は、 ハッシュアルゴリズムと形式を識別します$
.
、/
、0
–9
、A
–Z
を使用します、a
–z
は、以下で構成される 標準のBase 64エンコード アルファベットとは異なります。したがって、合計の長さはそれぞれ59バイトまたは60バイトです。
2a形式を使用する場合、60バイトが必要です。したがって、MySQLの場合、 CHAR(60) BINARY
またはBINARY(60)
を使用することをお勧めします( を参照)_ binおよびbinary照合順序 の違いについて).
CHAR
はバイナリセーフではなく、等価性はバイト値だけでなく実際の照合に依存します。最悪の場合、A
はa
と等しいものとして扱われます。詳細については、 The _bin
およびbinary
照合を参照してください 。
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へのデコードは次のようになります。
$<id>$
は3ビットで表すことができます。<cost>$
は5ビットで表すことができます。これらを1バイトにまとめます。1 + 16 + 23
あなたは上記のリンクでもっと読むか、あるいはGitHubで my PHP implementation を調べることができます。
あなたが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に見つかった脆弱性について常に最新の情報を入手し、リリースノートを確認するようにしてください。デフォルトのアルゴリズムが変更されたことがある場合は、その理由を確認し、新しいアルゴリズムを使用するかどうかについて十分な情報に基づいて決定することをお勧めします。
たとえばMD5ハッシュでできることのように、これを保存するためにできる巧妙なトリックはないと思います。
私はあなたの最善の策はそれが常に60文字の長さであるのでCHAR(60)
としてそれを保存することであると思います