Методы шифрования. Необратимое шифрование. Симметричное шифрование. Подбор пароля. Генерация пароля

Необратимое шифрование

При необратимом шифровании информация зашифровывается таким образом, что не подлежит обратной расшифровке. На первый взгляд это может показаться странным, но в действительности такой метод шифрования используется очень часто. Функция, с помощью которых реализуется однонаправленное шифрование, называются функциями хэширования. При использовании таких функций создается уникальный "отпечаток" строки. Наиболее часто в качестве алгоритма хэширования используется алгоритм MD5, реализовать который можно с помощью одноименной функции:

string md5($str [, $raw_output])

В качестве обязательного аргумента функция принимает строку $str, которую необходимо зашифровать и возвращает ее уникальный 128-битовый отпечаток (хэш-код). Если необязательный аргумент $raw_output имеет значение true, то возвращается бинарная строка из 16 символов. Вероятность того, что две строки дадут одинаковый хэш-код, стремиться к нулю.

Примечание. Аналогичная функция md5_file() часто используется для создания уникального хэш-кода объемных файлов, которые передаются по сети. Загрузив файл, всегда можно проверит его целостность, вычислив код по алгоритму md5 и сравнив полученный результат с хэш-кодом, представленным распространителем. Это позволяет отследить повреждения файла, вызванные передачей через сеть, а также предотвращает фальсификацию файла. Такой способ часто применяют при распространении объемных дистрибутивов.

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

Примечание. Такая схема авторизации не позволяет получить непосредственный доступ к паролям, даже если происходит хищение базы данных. В этом случае злоумышленник вынужден тратить значительное машинное время на перебор паролей по словарю, поэтому пароли вида W3t6,8yt6P практически не поддаются расшифровке, в тоже время необратимое шифрование не сможет защитить от перебора при пароле вида 12345.

При помощи функции md5() можно зашифровать различные данные, к примеру пароли пользователя.

Использование функции md5()

<?php
$maks_password="dghbcdj27hg"; //Сохраненный пароль пользователя
$maks_cipher=md5($maks_password); //Сохраненный хэш-код пароля
//Пароль пользователя вводимй при посещении странички
$user_password="dghbcdj27hg";
//Хэш-код пароля пользователя, вычисляемый при посещении странички
$user_cipher=md5($maks_password);
//Если хэш-коды совпадают то пароль верный
if($maks_cipher==$user_cipher)
{
echo "Hello, Maks";
}
else
{
echo "Введен не верный пароль";
}
?>

Для этих же целей используется функция crypt(), которая имеет следующий синтаксис:

string crypt($str [, $salt])

Аргумент $strпредставляет собой предназначенную для шифрования строку. К примеру, если передавать этой функции строку с паролем "dghbcdj27hg" и аргумент $salt, равный "ttt", то будет возвращена строка "ttqHdgPBP2/UI", которая не может быть дешифрована. Однако, поскольку результат работы функции строго определен в том смысле, что при вызове с одинаковыми параметрами $str и $salt функция возвращает один и тот же результат, ее можно использовать для проверки паролей.

Примечание. В UNIX-подобных ситемах и Windows хэш-код, возвращаемый функцией crypt(), не совпадает. В UNIX-подобной операционной системе результат функции crypt() можно использовать для автоматического выполнения файла .htpasswd, используемого совместно с конфигурационным файлом .htaccess для защиты директории паролем.

Использование функции crypt()

<?php
$maks_password="dghbcdj27hg";
$maks_crypt=crypt($maks_password, 'ttt');
echo $maks_crypt;
$user_password="dghbcdj27hg";
$user_crypt=crypt($maks_password, 'ttt');
if($maks_crypt==$user_crypt)
{
echo "<br>Пароли совпадают ";
}
else
{
echo "Введен неверный пароль";
}
?>

В окне веб-браузера это будет выглядеть ТАК.

Для однонаправленного шифрования можно также использовать функцию crc(), вычисляющую 32-битовую контрольную сумму исходной строки:

int crc($str)

Для работы с паролями эта функция, как правило не применяется, поскольку создает лишь 32-битовый хэш-код. Обычно этой функцией пользуются для проверки совпадения данных . С помощью этой функции, к примеру, удобно проверять, был ли изменен файл со времени последнего просмотра, совпадаютли перемещенные данные и т.д.

Симметричное шифрование

При симметричном шифровнии строки шифруются с помощью ключа, который известен как отправителю так и получателю. В РНР алгоритмы симметричного шифрования реализованы в библиотеке mcrypt; ознакомиться с полным набором функций и алгоритмов этой библиотеки можно на сайте http://www.php.net. Функции mcrypt работают, только если подключена библиотека mcrypt.

Примечание. Как и любое расширение, по умолчанию библиотека mcrypt в РНР5 отключена. Для того, чтобы ее подключить, необходимо убрать комментарий напротив строки extension=php_mcrypt.dll в конфигурационном файле php.ini. Кроме того, необходимо скопировать в системную директорию C:/Windows/system32 библиотеку libmcrypt.dll из дистрибутива РНР. Если данная библиотека не входит в состав дистрибутива РНР, то ее следует загрузить из сети, например по ссылке http://www.softtime.ru/libmcrypt.dll.

Рассмотрим пример, в котором строка зашифровывается и расшифровывается при помощи алгоритма 3DES(Triple-DES).

Использование симметричного шифрования

<?php
//Шифруем пароль
$user_password="dghbcdj27hg";
$key="Это секретный код";
//Шифруем пароль с использованием секретного ключа $key
$user_crypt=mcrypt_ecb(MCRYPT_3DES, $key, $user_password, MCRYPT_ENCRYPT);
echo "Зашифрованный пароль - $user_crypt <br>";
//Расшифровываем пароль
$user_crypt=mcrypt_ecb(MCRYPT_3DES, $key, $user_crypt, MCRYPT_DECRYPT);
echo "Расшифрованный пароль -$user_crypt";
?>

В окне веб-браузера это будет выглядеть ТАК.

В данном примере, пароль, размещенный в переменной $user_password, сначала шифруется функцией mcrypt_ecb() с применением ключа $key, а затем проводится его обратная дешифрация.

Подбор пароля

Как видно из рассмотренных примеров, для шифрованию паролей зачастую проще прибегать к необратимому шифрованию. Однако это не значит, что пароль, особенно простой, невозможно подобрать. Рассмотрим простейший скрипт подбора пароля методом перебора символов из массива $arr. При этом пароли располагаются в файле password, расположенном в той же директории,что и скрипт. Переменная max_number задает максимальный размер подыскиваемого пароля.

Примечание. Обычно подбор осуществляется не для каждого отдельного пароля, а для целой совокупности — ведь для каждого пароля перебираются одни и те же значения, следовательно можно экономить время, если обрабатывать все четыре пароля из файла password за один раз. Кроме того, реальный инструмент зачастую реализуют на компилируемом, а не интерпретируемом языке программирования.

Подбор пароля, зашифрованного с помощью MD5

<?php
//Устанавливаем неограниченное время выполнения скрипта
set_time_limit(0);
//Читаем пароли из файла password
$pass=file("password");
foreach($pass as $password)
{
//Замеряем время, затраченное на подбор пароля
$begin=time();
echo decrypt_md5(trim($password),"");
$end=time();
echo "(На подбор затрачено ".($end-$begin)."секунд)<br>";
}
//Функция символического подбора пароля
//$pass-расшифрованный пароль
// $answer- текущий ответ, при первом вызове - пустая строка

function decrypt_md5($pass, $answer)
{
$arr=array('a','b','c','d','e','f',
'g','h','i','j','k','l','m','n','o','p',
'q','r','s','t','u','v','w','x','y','z');
//Будем считать, что пароль не превышает
//4 символов

$max_number=3;
if(strlen($answer)>$max_number) return;
for($j=0; $j<count($arr); $j++)
{
$temp=$answer.$arr[$j];
if(md5($temp)==$pass)return $temp;
//Рекурсивно вызываем функцию для увеличения
//длины подбираемого пароля

$result=decrypt_md5($pass, $temp);
//Если функция возвращает не пустую строку,
//следовательно, найден ответ и дальше искать не следует

if(strlen($result)>0) return $result;
}
}
?>

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

После этого содержимое файла password разбиваются на строки, помещаемые в массив $pass, элементы которого в цикле передаются рекурсивной функции decrypt_md5().

Примечание. Следует отметить, что строки массива $pass пропускаются через функцию trim(), для того чтобы избавиться от невидимых символов \r\n, которые могут оставаться в конце строк.

Функция перебирает значения от а через ab, ac и до azzz, и как только временная переменная $аanswer принимает значение аааа, функция переходит к символу b и перебирает пароли до bzzz. Таким образом перебираются все символы из массива $arr. Как только пароль найден, функция возвращает его и выходит из рекурсивного цикла благодаря проверке:

if(strlen($result)>0) return $result;

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

Генерация пароля

Для генерации паролей воспользуемся случайной выборкой из массива элементов. Можно управлять частотой появления символов в пароле, добавлением дублирубщих элементов в массиве. Например, часто в массив -источник добавляются дублирующие буквы верхнего регистра. Следует подавлять такие желания, т.к. изменение частоты символов в пароле играет на руку злоумышленникам, которые, зная особенности генерации паролей, могут значительно сократить время подбора.

Генератор паролей

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=windows-1251">
<title>Генератор паролей</title>
</head>

<body>
<form action="" method="post">
<input name="number" type="text" value="8" size="25">
<input name="" type="submit" value="Генерировать">
</form>
<?php
//Параметр $number указывае количество символов в пароле
echo htmlspecialchars(generate_password($_POST['number']));
function generate_password($number)
{
$arr=array('a','b','c','d','e','f',
'g','h','i','j','k','l','m','n','o','p',
'q','r','s','t','u','v','w','x','y','z',
'A','B','C','D','E','F','G','H','I','J',
'K','L','M','N','O','P','Q','R','S','T',
'U','V','W','X','Y','Z', '1','2','3','4',
'5','6','7','8','9','0', ',','.','(',')',
'[',']','!','?','$','^','%','@','*','$',
'<','>','/','|','+','-','{','}','~','`');
//Генерируем пароль
$pass=" ";
for($i=0; $i<$number; $i++)
{
//Вычисляем случайный индекс массива
$index=rand(0, count($arr)-1);
$pass.=$arr[$index];
}
return $pass;
}
?>
</body>
</html>

В окне веб-браузера это будет выглядеть ТАК.




  • Другие |
назадвверхвперед
Rambler's Top100