2016-11-02 3 views
0

Чтобы создать безопасный безопасный URL-адрес для сброса пароля или активации электронной почты, какая из этих функций будет более безопасной, bin2hex или base64_encode в следующем приложении?bin2hex vs base64_encode для случайного хеш-маркера?

1. Создать токен (используя один из них):

$token = bin2hex(openssl_random_pseudo_bytes(32)); 
$token = strtr(base64_encode(openssl_random_pseudo_bytes(64)), "+/=", "XXX"); 

2. Хранить в базе данных:

$token_hash = password_hash($token, PASSWORD_BCRYPT); 
INSERT INTO hash_table SET token_hash='$token_hash', series='X' 

3. Проверка маркера:

SELECT token_hash FROM hash_table WHERE series='X' 
if (password_verify($hash_from_url,$token_hash)) { 
    // Success 
} 

Я заметил, что когда $ hash_from_url составляет более 72 символов, это больше не имеет значения.

Но не лучше ли использовать base64, чтобы получить 61 различный символ, а не bin2hex, который использует только 16, предполагая, что я использую большее количество случайных байтов для одинаково длинной строки, то есть 72 символа длины ?

ответ

1

Сама кодировка фактически ничего не меняет в отношении безопасности.

Как вы уже указали, bin2hex() вернет более длинные строки, как base64_encode(), за то же количество байтов из-за меньшей базы возможных символов. Это означает, что если указана длина токена, кодировка base64 производит токены с большей энтропией и поэтому лучше подходит.

Если ваши жетоны достаточно прочны (мин. 20 символов a..z, A..Z, 0..9), вы можете использовать простую хеш-функцию (например, SHA-256) без использования соления и перетяжки ключей вместо пароля_hash , Таким образом, вы можете создавать хэши для поиска в базе данных.

Некоторое время назад я написал small class для генерации значков base62 определенной длины для сбрасывания пароля, возможно, вы хотите посмотреть на код.

+0

Спасибо, я думал, что более безопасно НЕ хранить хеш, который был отправлен пользователю по электронной почте, но вместо этого хранить серийный идентификатор, а затем сравнить предоставленный пользователем хэш с зашифрованным хешем с помощью password_hash? Зачем мне нужен хеш для поиска? Разве это небезопасно из-за временных атак? – Niclas

+0

@ Никлас - Хорошие вопросы. Только для уточнения, вы не отправляете хэш пользователю, вместо этого ссылка должна содержать исходный токен. Тогда временная атака не работает, потому что ваше серверное приложение снова вычисляет хэш и ищет этот хеш. Хэш не позволяет делать выводы о сходствах двух оригинальных токенов. Проблема с идентификатором заключается в том, что вы также должны хранить его где-то, и вы должны отправить его по ссылке. Это позволяет использовать более короткие токены (сохраняемые при растяжении ключей), но URL-адрес растет из-за включенного идентификатора. – martinstoeckli

+0

Еще раз спасибо, я, наверное, смешиваю токен с хешем в моем примере, что делает его несколько запутанным. Я проверю ваш класс, а также прочитаю больше о растяжении ключей. У меня нет проблем с длинными жетонами, и я чувствую, что они более безопасны, но, может быть, 128 символов base62 переполнены? Я скрываю ссылку сброса за HTML, но, возможно, есть проблема, если кто-то читает обычную версию и перерыв URL. Но должен ли я жертвовать безопасностью для меньших почтовых клиентов? – Niclas