Многие из Вас знают, что есть такое алгоритм шифрования MD5. Практически все используют его для хеширования паролей пользователей. Но перейдем немного к истории.
Message Digest 5 (
Он же MD5) был разработан неким Рональдом Линном Ривестом, в далеком 1991 году. На основе данного алгоритма был построен приемник MD5 -
SHA-2. Хеш MD5 имеет размер в 128 бит и стандарт RFC 1321.
Уже в 1996 году Ганс Доббертин, сообщил о коллизиях в системе хеширования MD5. Из-за небольшой длинны хеша (128 бит или 16 байт) хеш не способен выдержать атаку типа "День рождения" или как еще ее называют "birthday-attack", принцип данной атаки заключается на парадоксе дней рождения, но мы уже отклонились от темы. Про парадокс можете почитать
. В 2004 году, проект "MD5CRK" смог вычислить уязвимости в алгоритме.
Почему MD5 устарел и небезопасен?
Ответ на этот вопрос лежит выше. Как и говорится в исторической хронике, алгоритм MD5 был скомпрометирован еще в 2004 году. На сегодняшний день, автор данного алгоритма сам призывает не использовать его алгоритм, а вместо MD5 использовать более устойчивые алгоритмы, такие как: SHA-512, Blowfish. Объясняет это он следующим: Цитата (не дословная): "Прогресс не стоит на месте, с каждым годом появляются новые технологии. На сегодняшний день алгоритм MD5 является не безопасным, поскольку на сегодняшний день компьютеры способны перебирать 1 миллион возможных комбинаций в секунду, и это не предел...".
Альтернативные алгоритмы. Их применение.
Поскольку мы имеем место быть PHP порталом, буду приводить примеры на языке PHP, и так приступим.
Я рассмотрю метод криптования Blowfish, польколку именно его я использую в большинстве своих проектов.
Самый простой способ, но не столь безопасный это использование следующего варианта:
Код (+/-)
<?php
function verefy($hash,$password){
return crypt($password, $hash) === $hash; }
function cryptPassword($password){
$salt = "$2a$08$";
return crypt($password, $salt); }
Теперь объясню что да как. Криптование методом Blowfish, при одном и том же пароле будет отдавать постоянно разный хеш (в отличии от MD5), для этого и нужно использование функции проверки. Но данный метод предусматривает хранение хеша и соли в базе. Для серьезных проектов не годится.
Теперь рассмотрим более серьезный вариант.
К примеру у нас есть таблица:
MySQL запрос (+/-)
CREATE TABLE `users_crypt` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`username` varchar(50) NOT NULL,
`password` char(60) NOT NULL,
UNIQUE
KEY `ux_username`
(`username`
)) ENGINE=InnoDB DEFAULT CHARSET=utf8;
Теперь напишем функции для работы с паролями:
Код функций (+/-)
function confirmPassword($hash, $password)
{
return crypt($password, $hash) === $hash; }
function hashPassword($password)
{
return crypt($password, '$2a$08$' . $salt); }
Пример использования при регистрации:
Код (+/-)
require_once __DIR__ . '/db.php';
require_once __DIR__ . '/functions.php';
$success = false;
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
$username = $_POST['username'];
$password = $_POST['password'];
$password = hashPassword($password);
$db->exec('insert into users_crypt(username, password) values (?,?)', $username, $password);
$success = true;
}
// display html form
И авторизация:
Код (+/-)
require_once __DIR__ . '/db.php';
require_once __DIR__ . '/functions.php';
$isAuth = -1;
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
$username = $_POST['username'];
$password = $_POST['password'];
$data = $db->queryOne('select id, password as hash
from users_crypt
where username=?', $username);
$isAuth = 0;
if ($data) {
if(confirmPassword($data['hash'], $password)){
$isAuth = 1;
}
}
}
// display html form
Почему именно Blowfish?
Алгоритм Blowfish при работе занимает больше процессорного времени, за счет этого делает подбор долгим и неэффективным по сравнению связки MD5+соль. При этом Blowfish довольно устойчив к коллизиям, и пока что еще не было обнаружено уязвимостей в алгоритме. Данный алгоритм используется в php фреймворке Laravel.
Явный показатель разницы затраченного процессорного времени на подбор:
$pswd = 'test';
for ($i = 0; $i < 1000; $i++) {
}
echo 'md5(1000 iters): '.$t.PHP_EOL;
//md5(1000 iters): 0.000318 sec
$pswd= crypt('test', '$2a$08$' . $salt); echo 'blowfish: '.$t.PHP_EOL;
//blowfish: 0.016532 sec
На криптование слова test, MD5 за 1000 прогонов потратил 0.000318 sec. В то время как на криптование этого же слова только 1 раз, Blowfish потратил 0.016532 sec.
Заключение
Исходя из всего изложенного, лично мое мнение, что перейти с MD5 на blowfish будет не так уж и плохо, да вы немного потеряете в производительности, но не настолько много, что бы жертвовать безопасностью только ради скорости работы. Лично мое кредо - "Безопасность превыше всего", а уже Вам выбирать стоит ли использовать данный алгоритм или остаться на старом, добром MD5