5
0

More than 5 years have passed since last update.

password_hash()ではパスワードが切り詰められる

Last updated at Posted at 2019-01-31

元ネタ

72文字を超えるパスワードを許容したい場合、password-hashを使うべきではない? - stack overflow
password_hash()の重要な制限
PHPマニュアル

PASSWORD_BCRYPT をアルゴリズムに指定すると、 password が最大 72 文字までに切り詰められます。

ほんとぉ?

試してみた

# php -v
PHP 7.2.7 (cli) (built: Jun 20 2018 08:21:26) ( NTS )
<?php
$pass72 = "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrst";
//strlen($pass72) => 72
$pass73 = "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstu";
//strlen($pass73) => 73

$hash73 = password_hash($pass73,PASSWORD_DEFAULT);

password_verify($pass72,$hash73);
// bool(true) <- !!!

というように、73 文字のパスワードのハッシュと 72 文字のパスワードが同じものとみなされてしまいました。
これはPASSWORD_DEFAULTの値がPASSWORD_BCRYPT、つまりCRYPT_BLOWFISHを使っているから(?)起こるらしいです。
少なくともPHP7.1以下ではBCRYPT以外使えないので、必ず起こります。(PHP7.2からは標準でArgon2iが使える。)

実用上問題なさそう

ところで、上のコードは

password_verify($pass73,$hash73);
// bool(true) <- !!!

でもあります。つまりpassword_verify()でも同様に切り詰められてから比較されるので、ユーザが72文字以上のパスワードを入力しても実用上問題はなさそうです。(ただし、90文字のパスワードを入力しても、72文字目までが同じ別のパスワードでクラックできる。)
下手にハッシュをはさんだりすると脆弱性の原因にもなりかねないので、とりあえずは72文字制限を受け入れておきましょう。どうしても気持ち悪いときはPHP7.2からpassword_hashの第二引数にPASSWORD_ARGON2I使えるようになっているので、そっちを使いましょう。

おわりに

今まで何も気にせず問題なく使ってきたのですが、知ってしまうと気持ち悪い挙動なので、今後は状況を見つつPASSWORD_ARGON2Iを使っていきたい感じ

5
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
0