Help us understand the problem. What is going on with this article?

password_verifyは本当にタイミングセーフなのか?

More than 3 years have passed since last update.

このコードには問題点がある.

<?php

$username = 'ユーザ名';
$password = 'パスワード';

$hashes = [
    'mpyw' => '$2y$10$p3v4KlSFqx11/84YF2xTJu4h5hQKhwsH5/X5bqoVgkY./.vFxf3HS',
];
$result = isset($hashes[$username]) && password_verify($password, $hashes[$username]);

password_verifyを実行するかしないかで大きく実行時間に差が現れるため,ユーザ名が存在すること・しないことがバレやすい.これではユーザ名をできるだけ保護したい目的で「ユーザ名またはパスワードのどちらかが違います」のようにメッセージを出したとしても意味が無くなってしまう.

では,ただpassword_verifyをとりあえず実行しておけばいいのか?というとそうでもない模様.

<?php

for ($i = 0; $i < 25; ++$i) {
    $hash = '$2y$10$' . str_repeat('A', $i + 1);
    $sum = 0.0;
    for ($j = 0; $j < 30; ++$j) {
        $start = microtime(true);
        password_verify('a', $hash);
        $end = microtime(true);
        $sum += $end - $start;
        unset($start, $end);
    }
    printf("%02d: %.5f\n", $i + 1, $sum / 30);
}

/*

01: 0.00015
02: 0.00013
03: 0.00014
04: 0.00016
05: 0.00020
06: 0.00016
07: 0.00013
08: 0.00014
09: 0.00015
10: 0.00015
11: 0.00013
12: 0.00015
13: 0.00015
14: 0.00016
15: 0.00020
16: 0.00018
17: 0.00015
18: 0.00014
19: 0.00017
20: 0.00013
21: 0.00013
22: 0.08747
23: 0.08111
24: 0.08496
25: 0.08421

*/

ダミーデータを (あり得る文字を使って) 22バイト用意しておけばいい感じに一律になりそうですね.

<?php

$username = 'ユーザ名';
$password = 'パスワード';

$hashes = [
    'mpyw' => '$2y$10$p3v4KlSFqx11/84YF2xTJu4h5hQKhwsH5/X5bqoVgkY./.vFxf3HS',
];
$result = password_verify(
    $password,
    isset($hashes[$username])
        ? $hashes[$username]
        : '$2y$10$abcdefghijklmnopqrstuv'
);
Why do not you register as a user and use Qiita more conveniently?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away