2013-06-29 8 views
1

Я новичок в программировании php и проблемах с безопасностью php, безопасно ли хешировать несколько раз пароль, другие через Интернет говорят, что он вызывает столкновения или это вообще небезопасно , поэтому мой вопрос заключается в том, что метод хэширования будет безопасным, если он будет реализован так. Я пробовал несколько вещей и комбинаций, и результаты не совпадают, но действительно ли это делает пароль mor безопасным?будет тройным хэшированием проходов сделать их более безопасными php,

$input_pass = 'example'; 
$step1 = md5($input_pass); 
$final_pass = hash('sha512',crypt(pi(),hash('sha512',$input_pass))); 

спасибо, :)

+0

Нет, это не делает его более надежным. Если вы используете php 5.5, посмотрите на функцию password_hash http://php.net/manual/en/function.password-hash.php Если вы используете меньше, чем этот взгляд в phpass http://www.openwall.com/phpass/ – Kris

+0

Да, это помогает против грубой силы. Но, как сказал Крис, используйте новые функции 5.5 или вы можете использовать backport для этой функции, когда у вас есть PHP 5.3 или выше. – AlucardTheRipper

+0

Pleeeez не используют md5 ша. Выберите более сильный алгоритм хеширования, такой как bcrypt, scrypt или PBKDF2, и добавьте соль к нему. Кроме того, ознакомьтесь с ответами справа в разделе Связанные. – DOK

ответ

20

Таким образом, чтобы показать, почему конкретно это эффектноплохо идея (мягко говоря), давайте рассмотрим код, который у вас есть:

$input_pass = 'example'; 

$step1 = md5($input_pass); 

Итак, вы сгенерировать MD5, а затем полностью игнорировать его ...

$t1 = hash('sha512',$input_pass); 

Теперь вы хэш пароля с SHA512

$t2 = crypt(pi(),$t1); 

, а затем запустить крипту над выходом pi() (в качестве входных данных для поля ввода пароля), проходя в SHA512 хэш как «соли» (подробнее об этом в секунду)

$final_pass = hash('sha512',$t2); 

И то хэш весь результат во второй раз ...

Теперь, чтобы понять, почему это так плохо, давайте посмотрим на выходах каждого шага:

$t1 = string(128) "3bb12eda3c298db5de25597f54d924f2e17e78a26ad8953ed8218ee682f0bbbe9021e2f3009d152c911bf1f25ec683a902714166767afbd8e5bd0fb0124ecb8a" 
$t2 = string(13) "3b5PQJpjs2VBk" 
$final_pass = string(128) "ec993177685eb6f2aa687d1202f47f7c5c0e17954fe1409115ed8b2170839029a065a189a3d2af6fe8d05869f7a6980743c199d7eb9d00c7e036af790231549a" 

Хм, подожди секунду, мне интересно. Попробуем изменить пароль на что-то еще. Сообщите foobar:

$t1 = string(128) "0a50261ebd1a390fed2bf326f2673c145582a6342d523204973d0219337f81616a8069b012587cf5635f6925f1b56c360230c19b273500ee013e030601bf2425" 
$t2 = string(13) "0aTQxuCXvbnbY" 
$final_pass = string(128) "6cd37aeccd93e17667563fadfae96d50427b5187cffb1c2865ee4bcce76d6c767f2b9b6c542988fd5559efb499d988b204e49b8ed60428db45e2ccb3945f33f2" 

Хммм, интересно. Первые 2 символа $t2 соответствуют первым двум символам $t1 ... Интересно, можем ли мы использовать это для использования этого кода. Давайте создадим немного грубой Якорь найти случайный пароль, который сталкивается с первых 2 символов этого SHA512:

$target = '3b'; 

$runs = 0; 

do { 
    $runs++; 
    $pass = genRandomPass(); 
    if ('3b' == substr(hash('sha512', $pass), 0, 2)) { 
     echo "Found match: $pass\n In $runs Runs\n"; 
     die(); 
    } 
} while (true); 

function genRandomPass() { 
    $length = mt_rand(8, 12); 
    $chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; 
    $charLen = strlen($chars); 
    $result = ''; 
    for ($i = 0; $i < $length; $i++) { 
     $result .= $chars[mt_rand(0, $charLen - 1)]; 
    } 
    return $result; 
} 

И запустить его:

~$ time php test.php 
Found match: olhUhIWp5Xd 
In 49 Runs 

real 0m0.013s 
user 0m0.004s 
sys  0m0.012s 

Уоу! В 0,013 секунды он выбрал случайное столкновение !!!Давайте попробуем:

$t1 = string(128) "3ba21ea28adb4543755bf62133eb0337569170c90ae4f3eaca9b777bf88f3a2eb9f9d0e40e4ff9e8844814ac7944ccf61e2222c184ebbf91e43fcdc227c80416" 
$t2 = string(13) "3b5PQJpjs2VBk" 
$final_pass = string(128) "ec993177685eb6f2aa687d1202f47f7c5c0e17954fe1409115ed8b2170839029a065a189a3d2af6fe8d05869f7a6980743c199d7eb9d00c7e036af790231549a" 

Yup! В 0,013 секунды процессорного времени я только что нашел столкновение для этого хэш-метода.

ПОЧЕМУ

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

Значит, вся энтропия пароля помещается в 2 символа. 2 символа, которые имеют по 64 комбинации. Таким образом, общая возможная энтропия конечного хэша составляет 4096 возможностей или 12 бит.

Сравните это Bcrypt, который обеспечивает 576 бит энтропии, и вы можете понять, почему это плохо ...

Заключение

Как я said before: Face It, криптография трудна, Дон Не пытайтесь что-то придумать, а используйте библиотеку. Есть много доступных.

Там не только абсолютно нет веской причины, чтобы изобрести сами ...

Проверить This Answer для разбивки различных доступных библиотек (которые в настоящее время рекомендуется).

+0

Но он все еще помогает сохранить оригинальный пароль, не так ли? – zerkms

+0

@zerkms: зависит от вашего определения. Он открывает это приложение. Кроме того, давайте представим, что злоумышленник получил эту базу данных и другую хешированную базу данных BCRYPT. И что пользователь использовал один и тот же пароль в каждом. Злоумышленник может использовать эту базу данных как фильтр Bloom, по которому кандидаты могут попробовать против bcrypt. Сокращение времени, чтобы атаковать базу данных BCrypt в 4096 году ... Что особенно важно ... – ircmaxell

3

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

Для более надежных паролей, однако, вы захотите заглянуть в соления ваших паролей (https://en.wikipedia.org/wiki/Salt_(cryptography)). Если ваш сайт когда-либо был скомпрометирован и данные украдены, соление поможет защитить от определенных видов атак, чтобы взломать сохраненные пароли.

+0

например: $ final_pass = crypt ('example', '$ 6 $ somesalt $'); Где «somesalt» - это случайная строка, состоящая из a-zA-Z./ Не нужно использовать hash(), а хеши совместимы с другими языками программирования или базами данных, так как все знают crypt(). – lathspell