パスワードハッシュ化
ユーザーのセキュリティを確保するために、パスワードを読み取り可能な形式で保存するのではなく、そのハッシュ(いわゆるハッシュ)のみを保存します。ハッシュから元のパスワードを逆算することはできません。ハッシュを作成するために安全なアルゴリズムを使用することが重要です。これには Nette\Security\Passwords クラスが役立ちます。
フレームワークは、Nette\Security\Passwords
型のサービスを security.passwords
という名前で DI コンテナに自動的に追加します。これには、dependency injection
を使用して渡してもらうことでアクセスできます。
use Nette\Security\Passwords;
class Foo
{
public function __construct(
private Passwords $passwords,
) {
}
}
__construct ($algo=PASSWORD_DEFAULT, array $options=[]): string
ハッシュ生成に使用する 安全なアルゴリズム を選択し、そのパラメータを設定します。
デフォルトでは PASSWORD_DEFAULT
が使用されます。つまり、アルゴリズムの選択は PHP
に任されます。より新しく、より強力なハッシュアルゴリズムが登場した場合、新しいバージョンの
PHP
でアルゴリズムが変更される可能性があります。したがって、結果のハッシュの長さが変わる可能性があることに注意し、十分な文字数(255
が推奨される幅)を格納できる方法で保存する必要があります。
cost パラメータを変更して bcrypt アルゴリズムのハッシュ化速度を設定する例:(2020 年のデフォルトは 10、パスワードのハッシュ化には約 80ms かかります。cost 11 では約 160ms、cost 12 では約 320ms です。遅いほど保護が向上し、速度 10〜12 はすでに十分な保護と見なされます)
// bcrypt アルゴリズムの 2^12(2^cost)回の反復でパスワードをハッシュ化します
$passwords = new Passwords(PASSWORD_BCRYPT, ['cost' => 12]);
dependency injection を使用:
services:
security.passwords: Nette\Security\Passwords(::PASSWORD_BCRYPT, [cost: 12])
hash (string $passwords): string
パスワードのハッシュを生成します。
$res = $passwords->hash($password); // パスワードをハッシュ化します
結果 $res
は、ハッシュ自体に加えて、使用されたアルゴリズムの識別子、その設定、および暗号化ソルト(同じパスワードに対して異なるハッシュが生成されることを保証するランダムデータ)を含む文字列です。したがって、たとえばパラメータを変更した場合でも、以前の設定を使用して保存されたハッシュも検証できるため、下位互換性があります。この結果全体がデータベースに保存されるため、ソルトや設定を別途保存する必要はありません。
verify (string $password, string $hash): bool
指定されたパスワードが指定されたハッシュに対応するかどうかを確認します。$hash
は、指定されたユーザー名またはメールアドレスに基づいてデータベースから取得します。
if ($passwords->verify($password, $hash)) {
// 正しいパスワード
}
needsRehash (string $hash): bool
ハッシュがコンストラクタで指定されたオプションに対応するかどうかを確認します。
これは、たとえばハッシュ化速度を変更する場合に役立ちます。検証は保存された設定に基づいて行われ、needsRehash()
が true
を返した場合、今回は新しいパラメータでハッシュを再作成し、データベースに再度保存する必要があります。このようにして、ユーザーがログインするときに保存されたハッシュが自動的に「アップグレード」されます。
if ($passwords->needsRehash($hash)) {
$hash = $passwords->hash($password);
// $hash をデータベースに保存します
}