Хранение зашифрованных данных в файле или базе данных

Задача
Требуется сохранить зашифрованные данные, которые в дальнейшем будут затребованы и расшифрованы вашим веб-сервером.

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

// шифруем данные $alg = MCRYPT_BLOWFISH;
$mode = MCRYPT_MODE_CBC;
$iv = mcrypt_create_iv(mcrypt_get_iv_size($alg,$mode),MCRYPT_DEV_URANDOM);
$ciphertext = mcrypt_encrypt($alg,$_REQUEST['key'],
$_REQUEST['data'],$mode,$iv);
// записываем зашифрованные данные
$dbh->query('INSERT INTO noc_list (algorithm,mode,iv,data)
values (?,?,?,?)',
array($alg,$mode,$iv,$ciphertext));

Для расшифровки данных получите от пользователя ключ и примените его к сохраненным данным:

$row = $dbh->getRow('SELECT * FROM noc_list WHERE id = 27');
$plaintext = mcrypt_decrypt($row->algorithm,$_REQUEST['key'],$row->data,
$row->mode,$row->iv);

Обсуждение
Программа save-crypt.php, показанная в примере 14.2, записывает зашифрованные данные в файл.

Пример 14.2.


save-crypt.php
function show_form() {
print<<<_FORM_



Encryption Key:

_FORM_;
}
function save_form() {
$alg = MCRYPT_BLOWFISH;
$mode = MCRYPT_MODE_CBC;
// шифруем данные
$iv = mcrypt_create_iv(mcrypt_get_iv_size($alg,$mode),MCRYPT_DEV_URANDOM);
$ciphertext = mcrypt_encrypt($alg, $_REQUEST['key'],
$_REQUEST['data'], $mode, $iv);
// записываем зашифрованные данные
$filename = tempnam('/tmp','enc') or die($php_errormsg);
$fh = fopen($filename,'w') or die($php_errormsg);
if (false === fwrite($fh,$iv.$ciphertext)) {
fclose($fh);
die($php_errormsg);}
fclose($fh) or die($php_errormsg);
Return $filename;
}
if ($_REQUEST['submit']) {
$file = save_form();
print "Encrypted data saved to file: $file";
} else {
show_form();
}

Пример 14.3 показывает соответствующую программу, get-crypt.php, которая принимает имя файла и ключ и выдает расшифрованные данные.

Пример 14.3.


get-crypt.php
function show_form() {
print<<<_FORM_
Encrypted File:

Encryption Key:

_FORM_;
}
function display() {
$alg = MCRYPT_BLOWFISH;
$mode = MCRYPT_MODE_CBC;
$fh = fopen($_REQUEST['file'],'r') or die($php_errormsg);
$iv = fread($fh,mcrypt_get_iv_size($alg,$mode));
$ciphertext = fread($fh,filesize($_REQUEST['file']));
fclose($fh);
$plaintext = mcrypt_decrypt($alg,$_REQUEST['key'],$ciphertext,$mode,$iv);
print "
$plaintext
";
}
if ($_REQUEST['submit']) {
display();
} else {
show_form();
}

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


Все, что находится после вектора, является зашифрованными данными.

Метод шифрования файла, реализованный в данном рецепте, предлагает защиту на случай, если атакующий получает доступ к серверу, на котором хранится файл. Без соответствующего ключа или огромных вычислительных затрат атакующий не сможет прочитать файл. Однако безопасность, которую обеспечивает этот зашифрованный файл, находится под угрозой, если данные, которые надо зашифровать, и ключ шифрования передаются между вашим сервером и броузерами пользователей в открытом виде. Любой, кто перехватывает или отслеживает сетевой трафик, получит возможность увидеть данные до того, как они будут зашифрованы. Чтобы предотвратить такой способ перехвата сообщений, следует использовать SSL.

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

Оцените статью: (0 голосов)
0 5 0

Статьи из раздела PHP на эту тему:
Не храните пароли на своем сайте
Обнаружение SSL-соединения
Проверка данных с помощью хеширования
Проверка надежности пароля
Работа с потерянными паролями

Вернуться в раздел: PHP / 14. Шифрование и безопасность