Каков хороший способ создать случайную «соль сайта», которая будет использоваться при создании токенов для поиска пароля? - PullRequest
14 голосов
/ 20 июля 2010

Я хотел бы создать хеш для всего сайта, который будет использоваться в качестве соли при создании токенов для поиска пароля.Я прыгал вокруг стека overoverflow, пытаясь понять, как лучше всего это сделать.

Вот процесс сброса:

Когда пользователь запрашивает электронное письмо для сброса пароля, код генерирует токен поиска:

$token = hash_hmac('sha256', $reset_hash* , $site_hash)

* $ reset_hash - это хеш, созданный с использованием phpassФункция HashPassword (), сохраненная в пользовательской таблице.

Затем я отправляю токен в URL на адрес электронной почты пользователя.Они щелкают до истечения времени ожидания токена в течение часа.Я сопоставляю их представление с токеном вызова, созданным на стороне сервера.Если он совпадает, то они вынуждены выбрать новый пароль и затем войти в систему.

Я хотел бы знать, как лучше всего сгенерировать ключ $ site_key.Я подумываю об использовании другого HMAC-хэша, который будет заполнен случайными числами:

$site_key = hash_hmac('sha256', MCRYPT_DEV_RANDOM, MCRYPT_DEV_RANDOM);

Это приведет к примерно так:

98bb403abbe62f5552f03494126a732c3be69b41401673b08cbfefa46d9e8999

Будет ли это случайным образом использоваться для этогоцель?Я слишком усложняю это или подхожу к этому неправильно?

Я был вдохновлен использовать HMAC этим ответом

РЕДАКТИРОВАТЬ: Я пытаюсьчтобы избежать шага «секретного вопроса», к которому призывают некоторые мои коллеги, я бы хотел, чтобы ссылка для сброса предоставила один шаг для сброса пароля.Поэтому я обеспокоен тем, что этот процесс будет достаточно безопасным, чтобы защитить систему, содержащую конфиденциальную информацию.

РАЗРЕШЕНО, на данный момент: Я собираюсь использовать одноразовый номер, описанный The Rook кактокен сброса.Спасибо всем за комментарии и отзывы.

1 Ответ

23 голосов
/ 20 июля 2010

Начнем с того, что вы не говорите о соли. Вы говорите о Cryptographic Nonce , и когда вы солите пароль, вы должны использовать Cryptographic Nonce. В случае сброса паролей это должно быть случайное число, которое хранится в базе данных. Не выгодно иметь «сайт соли».

Прежде всего, мне не нравится uniqid () , потому что это трудоемкий расчет, а время - очень слабое семя . rand () против mt_rand () , спойлер: rand () - полная хрень.

В веб-приложении хорошим источником безопасных секретов является неблокирующий доступ к пулу энтропии, например /dev/urandom. Начиная с PHP 5.3 приложения PHP могут использовать openssl_random_pseudo_bytes(), а библиотека Openssl будет выбирать лучший источник энтропии на основе вашей операционной системы, в Linux это означает, что приложение будет использовать /dev/urandom. Этот фрагмент кода от Скотта довольно хорош :

function crypto_rand_secure($min, $max) {
        $range = $max - $min;
        if ($range < 0) return $min; // not so random...
        $log = log($range, 2);
        $bytes = (int) ($log / 8) + 1; // length in bytes
        $bits = (int) $log + 1; // length in bits
        $filter = (int) (1 << $bits) - 1; // set all lower bits to 1
        do {
            $rnd = hexdec(bin2hex(openssl_random_pseudo_bytes($bytes)));
            $rnd = $rnd & $filter; // discard irrelevant bits
        } while ($rnd >= $range);
        return $min + $rnd;
}

function getToken($length=32){
    $token = "";
    $codeAlphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
    $codeAlphabet.= "abcdefghijklmnopqrstuvwxyz";
    $codeAlphabet.= "0123456789";
    for($i=0;$i<$length;$i++){
        $token .= $codeAlphabet[crypto_rand_secure(0,strlen($codeAlphabet))];
    }
    return $token;
}
...