В стандартной установке PHP предоставляет нам некотрые функции для шифрования, например, crypt() и md5(). Остальные нужно явно указывать при компиляции (mcrypt, mhash, cURL).

Функция crypt() выполняет односторонее DES-шифрование. Ей нужно передать обычный текст для шифрования, чтобы получить зашифрованный:

<?php

print crypt ("text", "parametr");

?>

Если второй параметр не указать, то PHP автоматически сгенерирует случайную пару символов для базиса шифрования. При помощи crypt() можно шифровать и по алгоритму md5 ( не только при помощи функции md5() ). Достаточно установить константу CRYPT_MD5 в 1.

Зададим базис, начинающийся с $1$ для использования md5 в функции crypt():

<?php

print crypt ("text", "$1$parametr");

?>

Большой набор алгоритмов и режимов шифрования включает в себя библиотека mcrypt. Итак, зашифруем и расшифруем информацию с помощью алгоритма Blowfish.

<?php

$key = "My cool key"; // просто текст
$data = "My secret data"; // инфа для шифрования
$alg = MCRYPT_BLOWFISH;
$mode = MCRYPT_MODE_CBC;
$iv = mcrypt_create_iv (mcrypt_get_iv_size ($alg, $mode),
MCRYPT_DEV_URANDOM);
$encrypted_data = mcrypt_encrypt ($alg, $key, $data, $mode, $iv);
$plain_text = base64_encode ($encrypted_data);

print $plain_text."\n";
$decoded = mcrypt_decrypt ($alg, $key, base64_decode
($plain_text), $mode, $iv);
print $decoded."\n";

?>

Почти ничего не понятно, да :)? Сейчас постараюсь объяснить. Все данные шифруются и расшифроввываются с помощью функций mcrypt_encrypt() и mcrypt_decrypt(). Каждая их них принимает пять аргументов.

Первый аргумент - применяемый алгоритм. Все поддерживаемые
алгоритмы можно посмотреть, вызвав функцию mcrypt_list_algorithms().
Второй аргумент - это ключ шифрования, третий - данные, которые шужно зашифровать и наоборот.
Четвертый аргумент устанавливает режим шифрование или расшифровки.
Пятый аргумент - вектор инициализации
(IV), он используется режимами в качестве составляющей. Первый аргумент функции mcrypt_create_iv() - это длина вектора, второй - источник случайности (в данном случае - /dev/urandom).

Можно применять MCRYPT_DEV_RANDOM и MCRYPT_RAND. Но тогда надо вызывать функцию srand(), т.к. не все ОС поддерживают псевдоустройства случайных генераторов (это касается функции MCRYPT_RAND).

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

Сколько раз уже было сказано, что не нужно хранить пароли в
открытом виде на своих сайтах и директориях, доступных через веб, а большинство почему-то продолжают делать именно так =)!

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

mysql_connect ('localhost', $_ENV['MYSQL_USER'],
$_ENV['MYSQL_PASSWORD']);

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

SetEnv MYSQL_USER "user"
SetEnv MYSQL_PASSWORD "your_pass"

Этот файл нужно включить в директиву <VirtualHost> в главном конфигурационном файле:

Include "/path_to_file/"

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

<?php

$word = 'some_word';
$id = 100;
$hash = md5 ($word . $id);
print<<<_HTML_
<input type="hidden" name="id" value="$id">
<input type="hidden" name="idhash" value="$hash">
_HTML_;

?>

После получения обратно проверяем:

<?php

$word = "some_word";
if (md5($word . $_REQUEST['id']) == $_REQUEST['idhash']) {
$id = $_REQUEST['id'];
} else {
die ("Invalid data");
}

?>

Для использования хеша в cookie изменим немного этот скрипт:

[skip]
....
$cookie_value = 'm0zg';
$hash = md5 ($word . $id);
setcookie ('name', join(' | ', array($cookie_value, $hash)));

Проверяем полученное:

<?php

$word = 'some_word';
list ($cookie_value, $cookie_hash) = explode (' | ',
$_COOKIE['name'], 2);
if (md5($word . $cookie_value) == $cookie_hash) {
$name = $cookie_value;
} else {
die ("Invalid data");
}

?>

Конечно, если кто-то узнает это секретное слово, то вся работа впустую. Тут можно либо менять его постоянно, либо пользоваться переменной $id, т.е. несколько разных слов, выбранных с помощью $id%10 (если 10 слов). Можно использовать модуль mhash, тут вы не будите ограничены хешами в md5. Он поддерживает несколько алгоритмов
хеширования.

А теперь хотелось бы затронуть тему шифрования почты. Использовать будем GPG (ибо Open Source!). Сначала код, а потом пояснения.

<?php

$message = escapeshellarg($message);
$gpg_path = '/usr/local/bin/gpg';
$sender = '[email protected]';
$rcpt = '[email protected]';
$home = '/home/user';
$user_env = 'user';
$cmd = "echo $msg | HOME=$home USER=$user_env $gpg_path " .
'--quit --no-secmem-warning --encrypt --sing --armor
' .
"--recipient $rcpt --local-user $sender";

$message = '$cmd'; mail($rcpt, 'GPG Mailer', $message);

?>

С начала мы вызываем программу GPG, расположенную в
/usr/local/bin/gpg для шифрования сообщения из $message. Она использует закрытый ключ, который принадлежит Вам ($sender), и открытый ключ, принадлежащий $rcpt. Теперь только он сможет расшифровать Ваше сообщение.

Установка переменных окружение HOME и USER указывает GPG, где ей нужно искать свои настройки шифрования ($HOME/.gnupg/secring.gpg).
Параметры --quiet и --no-secmem-warning подавляют предупреждения GPG, которые в противном случае были бы сгенерированы и добавились к тесту сообщения.

Параметры --encrypt и --sing заставляют GPG зашифровать
сообщение и подписать его. Шифрование сообщение закрывает его от любого, кроме адресата. В подписи содержится информация о том, кто составил сообщение и когда.

Параметр --armor генерирует простой текст вместо двоичного кода, для более удобной рассылки.

Обычно закрытые ключи защищаются с помощью идентификационной фразы. Если взломщик скопирует закрытый ключ, защищенный идентификационной фразой, то он ничего не сможет сделать с письмом, т.к. GPG запрашивает её при расшифровке. В этом коде эта фраза не используется.

Очень много можно написать по этой теме, но статью сильно растягивать не хочется =).

Ссылки по теме:

http://www.php.net/md5
http://www.php.net/mhash
http://www.php.net/crypt
http://www.php.net/mcrypt

 

 
     
     
Назад
by m0zg
Вперед