2011-03-06 2 views
6

Должен ли я использовать if(strcmp(md5($string),$hash)==0) или if(md5($string)==$hash)Каков наилучший способ сравнить хешированные строки? (PHP)

+0

Используйте 'strcmp' в пользовательских настройках сортировки. Для «нормального» использования сравнение строк напрямую проще и легче читать. –

+6

Для всех, кто читает эту тему, [вы, вероятно, не должны этого делать ** вообще **] (http://phpsadness.com/sad/47). – ereOn

+1

Если вы хотите просто сравнить хэши надежно, просто используйте '==='. Если вы действительно заботитесь о безопасности и потенциальных атак времени (даже несмотря на дрожание сети), вы должны взглянуть на [это] (https://github.com/delight-im/Faceless/issues/4) или [это] (https://github.com/delight-im/Faceless/pull/5) или используйте функцию 'hash_equals()' (PHP 5.6+). – caw

ответ

0

== был показан другими пользователями здесь чрезвычайно ненадежны. Вместо этого вы должны использовать strcmp().

Третий вариант, если вы действительно хотите использовать оператор сравнения, является использование ===, который не выполняет типа принуждение любого рода, и, следовательно, сохраняет типы и значения для целей сравнения.

+0

Какой из них имеет лучшую производительность? – webnat0

+0

==, потому что только одно сравнение, как мой пост ниже сказал –

+3

@ Da9: ... и никакой вызов функции. –

-4

Я думаю, что if(md5($string) == $hash) лучше, потому что у вас есть только одно сравнение вместо 2 (stcmp & ==).

md5 генерирует только ascii-символы, которые не нуждаются в двоичном безопасном сравнении.

+0

Обратите внимание на @MM. Во-вторых, md5 устарел (доказал, что его можно взломать). Используйте sha (лучше, не самый лучший). – Symba

+0

Конечно, вы должны использовать sha over md5. Но вопроситель спросил, что он должен использовать. Если кто-то спросит вас: «Вы хотите клубничное мороженое или шоколадное мороженое?», Вы не можете ответить «Я принимаю ванильное мороженое». Кроме того, вопрос заключается не в использовании хеш-алгоритма, а в сравнении значений. –

+0

Здесь мы не говорим о мороженое, но о безопасности. Поэтому ответ действительно «не используйте ничего из того, что вы предложили здесь!». И BTW: Также SHA-1 ** не должен ** использоваться для паролей. – rugk

15

Если вы сравниваете строки, используйте strcmp или ===. Люди предпочитают ===, потому что strcmp может ввести в заблуждение (он возвращает 0 по успеху, wat).

Вы должны использовать ===, а не ==. == преобразует оба операнда в целые числа, если они могут быть интерпретированы как таковые, и поскольку хеш MD5 не вписывается в целое число, они будут усечены вокруг половины. Поэтому только первые половины хэшей должны быть равны. См. http://phpsadness.com/sad/47.

Если вы используете хеширующие пароли, подумайте об использовании медленного и сильного алгоритма хеширования, такого как PBKDF2, а не MD5.

+4

Ничего себе ... это действительно грустно. – BoltClock

20

Вы должны быть очень осторожны при сравнении хешей непосредственно для таких вещей, как аутентификация, поскольку вы можете открыть окно для временной атаки.

Хотя это звучит очень противоречиво, вы должны полностью сравнить строку, избегая любых оптимизаций (то есть, выходите рано, если символ отличается).

Вот некоторые ссылки о проблеме:

А вот некоторые идеи для того, чтобы исправить это:

2

Если вы используете что-то более новое, чем PHP 5.6 (и в том числе), вы должны использовать timing attack safe string comparison функцию.

if (hash_equals($expected, $correct)) { 

} 

(Если вы на PHP 5.5 или выше, see here for equivalents.)

+0

Единственный правильный ответ. –

0

На самом деле вы должны использовать password_verify для этого, а также использовать все другие password_* функции. Они доступны в PHP> = 5.5.0.

В качестве резерва вы можете использовать this polyfill. В настоящее время он работает с PHP> = 5.3.7.

И если вы действительно не можете/не хотите использовать это, все равно hash_equals (и полиполняет для этого) как @MM. уже сказал.

Смежные вопросы