ハッシュ化されたパスワードフィールドに使用するデータタイプと長さ
-
05-07-2019 - |
質問
パスワードハッシュがどのように機能するかわかりません(後で実装します)が、データベーススキーマを今すぐ作成する必要があります。
パスワードを4〜20文字に制限することを考えていますが、ハッシュ文字列を暗号化した後に理解できるように、長さが異なります。
では、これらのパスワードをデータベースに保存する方法は?
解決
更新:ハッシュ関数を使用するだけでは、パスワードを保存するのに十分ではありません。詳細な説明については、このスレッドに関するGillesの回答をお読みください。
パスワードには、BcryptやArgon2iなどのキー強化ハッシュアルゴリズムを使用します。たとえば、PHPでは、 password_hash()関数を使用します。デフォルトでBcryptを使用します。
$hash = password_hash("rasmuslerdorf", PASSWORD_DEFAULT);
結果は、次のような60文字の文字列です(ただし、一意のソルトが生成されるため、数字は異なります)。
$2y$10$.vGA1O9wmRjrwAVXD98HNOgsNpDczlqm3Jq7KnEd1rVAGv3Fykk1a
SQLデータ型 CHAR(60)
を使用して、Bcryptハッシュのこのエンコードを保存します。この関数は16進数の文字列としてエンコードしないため、バイナリで保存するために16進数を簡単に解除することはできません。
他のハッシュ関数にはまだ使用できますが、パスワードを保存するためではありません。そのため、2008年に書かれた元の回答を以下に示します。
使用するハッシュアルゴリズムによって異なります。ハッシュは、入力に関係なく、常に同じ長さの結果を生成します。バイナリハッシュの結果を一連の16進数としてテキストで表すのが一般的です。または、 UNHEX()
関数は、16進数の文字列を半分に減らします。
- MD5は128ビットのハッシュ値を生成します。 CHAR(32)またはBINARY(16)を使用できます
- SHA-1は、160ビットのハッシュ値を生成します。 CHAR(40)またはBINARY(20)を使用できます
- SHA-224は、224ビットのハッシュ値を生成します。 CHAR(56)またはBINARY(28)を使用できます
- SHA-256は、256ビットのハッシュ値を生成します。 CHAR(64)またはBINARY(32)を使用できます
- SHA-384は、384ビットのハッシュ値を生成します。 CHAR(96)またはBINARY(48)を使用できます
- SHA-512は、512ビットのハッシュ値を生成します。 CHAR(128)またはBINARY(64)を使用できます
- BCryptは、実装依存の448ビットのハッシュ値を生成します。 CHAR(56)、 CHAR(60)、CHAR(76)、BINARY(56)またはBINARY(60)
2015年現在、NIST SHA-256の使用を推奨相互運用性を必要とするハッシュ関数のアプリケーションの場合、以上。ただし、NISTでは、これらの単純なハッシュ関数を使用してパスワードを安全に保存することはお勧めしません。
より少ないハッシュアルゴリズムには用途があります(交換用ではなく、アプリケーションの内部など)が、クラック可能性が知られている。
他のヒント
各ハッシュアルゴリズムは常に同じ文字数に評価されるため、実際にはCHAR(ハッシュの長さ)を使用してMySQLのデータ型を定義できます。たとえば、SHA1は常に40文字の16進数を返します。
ソルトの価値のあるに関するこのウィキペディアの記事をご覧ください。考え方は、データのセットビットを追加してハッシュ値をランダム化することです。これにより、誰かがパスワードハッシュへの不正アクセスを取得した場合に、辞書攻撃からパスワードが保護されます。
固定長文字列として(VARCHAR(n)またはMySQLが呼び出す)。 ハッシュの長さは常に固定で、たとえば12文字です(使用するハッシュアルゴリズムによって異なります)。したがって、20文字のパスワードは12文字のハッシュに削減され、4文字のパスワードも12文字のハッシュになります。
常にパスワードハッシュアルゴリズムを使用します: Argon2 、 scrypt 、 bcrypt または PBKDF2 。
Argon2 は、2015年のパスワードハッシュコンペティションで優勝しました。 Scrypt 、 bcrypt および PBKDF2 は古いアルゴリズムです現在はあまり好まれないと考えられていますが、基本的には健全であるため、プラットフォームがArgon2をまだサポートしていない場合は、今のところ別のアルゴリズムを使用しても構いません。
パスワードをデータベースに直接保存しないでください。暗号化もしないでください。それ以外の場合、サイトが侵害された場合、攻撃者は復号化キーを取得するため、すべてのパスワードを取得できます。パスワードはハッシュする必要があります。
パスワードハッシュには、ハッシュテーブルハッシュや暗号化ハッシュとは異なるプロパティがあります。パスワードにMD5、SHA-256、SHA-512などの通常の暗号化ハッシュを使用しないでください。パスワードハッシュアルゴリズムは、 salt を使用します。これは一意です(他のユーザーや他のユーザーのデータベースでは使用されません)。ソルトは、攻撃者が一般的なパスワードのハッシュを事前に計算できないようにするために必要です。ソルトでは、すべてのアカウントの計算を再開する必要があります。パスワードハッシュアルゴリズムは、本質的に遅い— 余裕があります。攻撃者は多くの異なるパスワードを試行する必要があるため、速度が遅いと攻撃者はあなたよりもはるかに痛くなります。詳細については、パスワードを安全にハッシュする方法を参照してください。
パスワードハッシュは4つの情報をエンコードします:
- 使用されているアルゴリズムのインジケータ。これは、敏性に必要です。暗号の推奨事項は時間とともに変化します。新しいアルゴリズムに移行できる必要があります。
- 難易度または硬度のインジケータ。この値が高いほど、ハッシュを計算するためにより多くの計算が必要になります。これは、パスワード変更機能の定数またはグローバル構成値である必要がありますが、コンピューターが高速になるにつれて時間とともに増加するため、各アカウントの値を覚えておく必要があります。単一の数値を持つアルゴリズムもあれば、より多くのパラメーターを持つアルゴリズムもあります(たとえば、CPU使用率とRAM使用率を個別に調整するため)。
- 塩。ソルトはグローバルに一意である必要があるため、アカウントごとに保存する必要があります。ソルトは、パスワードが変更されるたびにランダムに生成される必要があります。
- 固有のハッシュ、つまりハッシュアルゴリズムでの数学計算の出力。
多くのライブラリには、この情報を単一の文字列として便利にパッケージ化するペア関数が含まれています。アルゴリズムインジケータ、硬度インジケータ、およびパスワードを受け取り、ランダムソルトを生成して完全なハッシュ文字列を返します。パスワードと完全なハッシュ文字列を入力として受け取り、パスワードが正しいかどうかを示すブール値を返すもの。普遍的な標準はありませんが、一般的なエンコードは
です$algorithm$parameters$salt$output
algorithm
はアルゴリズムの選択をエンコードする数字または短い英数字文字列、 parameters
は印刷可能な文字列、および salt
および output
は、 =
を終了せずにBase64でエンコードされます。
ソルトと出力には16バイトで十分です。 (Se
実際に使用しているハッシュアルゴリズムに依存します。正しく覚えていれば、パスワードの長さはハッシュの長さとほとんど関係ありません。使用しているハッシュアルゴリズムの仕様を調べ、いくつかのテストを実行し、そのすぐ上で切り捨てます。
ハッシュはビットのシーケンスです(アルゴリズムに応じて、128ビット、160ビット、256ビットなど)。 MySQLで許可されている場合、列はテキスト/文字型ではなくバイナリ型でなければなりません(SQL Serverデータ型は binary(n)
または varbinary(n)
)。ハッシュも塩にする必要があります。ソルトはテキストまたはバイナリの場合があり、対応する列が必要になります。
前方互換性のために、 TEXT
(無制限の文字数を保存)を使用する必要があります。ハッシュアルゴリズム(必要)は時間とともに強くなるため、このデータベースフィールドは時間とともにより多くの文字をサポートする必要があります。さらに、移行戦略によっては、新しいハッシュと古いハッシュを同じフィールドに保存する必要がある場合があるため、1種類のハッシュに長さを固定することはお勧めしません。
暗号化された文字列の最大文字列長を見つけて、それをVARCHAR型の文字長として設定するために、私は常にテストしました。保持するレコードの数によっては、データベースのサイズを大幅に改善できます。
vARCHAR(32)が適切です。 AESを使用する場合は、varbinaryを使用する方が適切です。