たとえば、フグでは次のようなものが返されます。
$2a$12$DEzG.CRsHpxpTOAHooQ.wuR6Xe9h6PxFPhOcOvf.lqDNw1TVYVnEO
これには、ハッシュ alg のタイプに関する情報が含まれており、salt が含まれています。多くのリソースは、この値をデータベースに保存するだけで安全だと言っています。しかし、パスワードの一般的なリストをこれらの値に対してテストして、それらの一部をクラックすることはできませんか?
パスワードハッシュのセキュリティは、情報が秘密であることから生じるものではありません。実際のシークレット、つまりハッシュ値の基礎となるパスワードは既に破棄しています。残りのハッシュは、この元のデータの一種のフィンガープリントです。セキュリティは、ハッシュから元のデータを導き出すことができないという事実に由来します。唯一の可能性は、考えられるすべてのパスワードを試して、どれが同じハッシュを生成するかを確認することです。ここでのセキュリティは、これが計算上非常に高価であり、有用な時間内に成功する可能性が低いという事実から来ています.
ソルトは、誰かがすでに計算済みの既知のハッシュ化されたパスワードのセットを使用するのを防ぐためにのみ導入され、攻撃者は可能なすべてのパスワードを一意のソルトで実際に再ハッシュする必要があります。ソルト自体は秘密ではなく、ハッシュ アルゴリズムも秘密ではありません。
要するに、はい、その値はデータベースに保存しても絶対に安全です。
によって生成されたハッシュcrypt()
は、特に保存することを目的としています。パスワード ハッシュ スキームがどのようなものであっても、誰かがデータベースの内容を手に入れた場合、パスワードを総当たり攻撃することができ、パスワード ハッシュをまったく保存しないという選択肢はありません。によって適用されるアルゴリズムcrypt()
は、ハッシュの計算にかなりの時間がかかるため、特別に選択されています。これは、1 つのパスワードのみをテストする場合には明らかではありませんが、何千ものパスワードを総当たり攻撃すると、非現実的なほど遅くなります。
しかし、パスワードの一般的なリストをこれらの値に対してテストして、それらの一部をクラックすることはできませんか?
パスワードの保存方法に関係なく、いつでも実行できます。crypt 関数はこれを防ぎませんが、非常に遅くなります。ユーザーが非常に一般的なパスワード (123456 など) を使用している場合、世界中のハッシュ アルゴリズムでユーザーを保護することはできません。
これらの単純なパスワードを許可せず、適切なハッシュ アルゴリズム (crypt() が提供する) を使用すると、パスワードを保護するために最善を尽くしたことになります。
誰かがあなたのデータベースにアクセスできる場合、ユーザーのパスワードごとに異なるソルトを使用する必要があるため、どちらの方法でもソルトにアクセスできます(データベースに保存する可能性が最も高い)。
ソルトのポイントは、レインボー テーブルが機能しないようにすることです。個人は、パスワードを特定するために、パスワードとソルトのすべての組み合わせを再ハッシュする必要があります。パスワードごとに異なるソルトを使用するため、パスワードごとに何百万ものハッシュを再生成する必要があります。
crypt に関するより良い情報がここにあります: Why does PHP crypt() prepend the salt to the hash?