PHP шифрование данных

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

Симметричное шифрование – это алгоритм шифрования, в котором используется один и тот же криптографический ключ как для шифрования, так и для расшифровки данных. Рассмотрим на PHP шифрование данных симметричным методом на основе алгоритма AES (Advanced Encryption Standard) – симметричного алгоритма блочного шифрования (размер блока 128 бит, ключ 128/192/256 бит). AES является одним из самых распространённых алгоритмов симметричного шифрования..

PHP шифрование данных AES

Как уже говорилось ранее, для шифровки и расшифровки потребуется ключ шифрования. Это может быть любая строка, но мы для его получения воспользуемся функцией, которая генерирует строку псевдослучайных байт длиной 40, и преобразуем полученный результат в шестнадцатеричное представление:

$bytes = openssl_random_pseudo_bytes(40);
$hex = bin2hex($bytes);

var_dump($hex);

На экран будет выведен результат следующего вида:

string(80) "5aa3c281e42ba7101f7227a7519d5e961c7bcf2b10a42914304bffc1afcebb1d2be98f53caa80d05"

Полученное значение мы будем использовать как секретный ключ шифрования и дешифрования данных (он должен храниться в тайне). Запишем его в переменную $key:

$key = "5aa3c281e42ba7101f7227a7519d5e961c7bcf2b10a42914304bffc1afcebb1d2be98f53caa80d05";

Теперь определим, что мы будем кодировать. Для первого примера возьмем обычную строку:

$data = 'Это строка закодирована симметричным алгоритмом шифрованием AES';

Мы будем шифровать данные алгоритмом AES с 192 битным ключом:

$method = "AES-192-CBC";

Все доступные методы шифрования можно посмотреть следующим образом:

var_dump(openssl_get_cipher_methods());

Имея данные для шифрования $data, выбранный метод $method и секретный ключ $key в PHP симметричное шифрование данных мы можем осуществить с помощью функции openssl_encrypt:

$encrypted = openssl_encrypt($data, $method, $key);

Выведем на экран результат с помощью var_dump($encrypted):

string(152) "qNiTUkY5GY63q2IjbZ034myIFAf7hyTX+dRJF4YjJmJCk15YqAccIigpECKlCmLEgft7WNUV3/yZVcSqxLO3aDDOoV/5oglU1hFRiLD9yBF9q6HrM0Ic2e0RCgXxaHFa6ae6dZ2mVzgSkZvZnasTYg=="

Чтобы расшифровать полученное значение, необходимо воспользоваться обратной функцией openssl_decrypt:

$decrypted = openssl_decrypt($encrypted, $method, $key);

Опять воспользуемся var_dump($decrypted):

string(107) "Это строка была закодирована симметричным шифрованием AES"

Конечный листинг примера симметричного шифрования/расшифровки данных на PHP будет следующий:

<?php

// Ключ шифрования
$key = "5aa3c281e42ba7101f7227a7519d5e961c7bcf2b10a42914304bffc1afcebb1d2be98f53caa80d05";
// Шифруемые данные
$data = 'Это строка была закодирована симметричным шифрованием AES';
// Метод шифрования
$method = "AES-192-CBC";

// Шифруем данные
$encrypted = openssl_encrypt($data, $method, $key);

// Смотрим результат
var_dump($encrypted);

// Дешифруем данные
$decrypted = openssl_decrypt($encrypted, $method, $key);

// Смотрим результат
var_dump($decrypted);

?>

PHP шифрование файлов AES

В PHP шифрование файлов от шифрования данных отличается лишь тем, что содержимое файла сначала необходимо прочитать, проделать с ним необходимые операции, а затем – записать.

Создадим обычный текстовый файл в текущей директории:

$ echo 'Этот файл кодирован на PHP с помощью симметричного алгоритма AES' > aes.txt

Ключ и метод шифрования мы возьмем из предыдущего примера, а данные для кодирования получим из файла aes.txt с помощью функции file_get_contents:

$key = "5aa3c281e42ba7101f7227a7519d5e961c7bcf2b10a42914304bffc1afcebb1d2be98f53caa80d05";
$method = "AES-192-CBC";
$file = 'aes.txt';

$contents = file_get_contents($file);

Закодируем содержимое файла и запишем его в новый файл aes-encrypted.txt с помощью функции file_put_contents:

$contetsEncrypted = openssl_encrypt($contents, $method, $key);

$fileEncrypted = 'aes-encrypted.txt';
file_put_contents($fileEncrypted, $contetsEncrypted);

Посмотрим содержимое полученного файла:

$ cat aes-encrypted.txt
u1IdVyyNwECahzAaN0DQdSPx4lDiXHKXWc8/yl6KLne3tcyT/vUD/96Z84wgZHyhWc0daYT7JxiShat9xUjdQEC5V2nLuuMZ1/yUmIsE4HKZcvZEki99e0gAdtP9M0vdo82rEUfFnKe78wT7/zeOs1PBLaQvpXWbM8VcVeEVzTc=

Осталось попробовать расшифровать этот файл и записать его:

$contents = file_get_contents($fileEncrypted);

$contentsDecrypted = openssl_decrypt($contents, $method, $key);

$fileDecrypted = 'aes-decrypted.txt';
file_put_contents($fileDecrypted, $contentsDecrypted);

Проверяем результат:

$ cat aes-decrypted.txt
Этот файл кодирован на PHP с помощью симметричного алгоритма AES

Конечный листинг симметричного шифрования файла на PHP алгоритмом AES:

<?php

// Ключ шифрования
$key = "5aa3c281e42ba7101f7227a7519d5e961c7bcf2b10a42914304bffc1afcebb1d2be98f53caa80d05";
// Метод шифрования
$method = "AES-192-CBC";
// Файл для шифрования
$file = 'aes.txt';

// Читаем содержимое файла
$contents = file_get_contents($file);

// Шифруем содержимое файла
$contetsEncrypted = openssl_encrypt($contents, $method, $key);

// Шифрованный файл
$fileEncrypted = 'aes-encrypted.txt';
// Записываем шифрованные данные в новый файл
file_put_contents($fileEncrypted, $contetsEncrypted);

// Читаем содержимое шифрованного файла
$contents = file_get_contents($fileEncrypted);

// Расшифровываем содержимое шифрованного файла
$contentsDecrypted = openssl_decrypt($contents, $method, $key);

// Расшифрованный файл
$fileDecrypted = 'aes-decrypted.txt';
// Записываем расшифрованные данные в новый файл
file_put_contents($fileDecrypted, $contentsDecrypted);

?>

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

Асимметричное шифрование отличается от симметричного тем, что для шифровки и расшифровки данных используется не один общий ключ, а два разных. Одним из самых распространенных алгоритмов асимметричного шифрования является RSA (аббревиатура от фамилий Rivest, Shamir и Adleman) — криптографический алгоритм с открытым ключом. В этом алгоритме для шифрования данных используется публичный ключ, а для расшифровки – секретный приватный ключ.

PHP шифрование данных RSA

Для работы с данным алгоритмом нам понадобятся публичный public.crt и приватный private.pem ключ. Получить их можно из консоли с помощью openssl. Сгенерируем пару rsa с ключом 2048 бит на 365 дней (“/C=RU/ST=MO/L=MOSCOW/O=POCKETADMIN/TECH=XX/CN=pocketadmin.tech/emailAddress=”example@pocketadmin.tech – информация о субъекте, который выпустил ключ):

$ openssl req -newkey rsa:2048 -nodes -keyout private.pem -out public.crt -x509 -days 365 -subj "/C=RU/ST=MO/L=MOSCOW/O=POCKETADMIN/TECH=XX/CN=pocketadmin.tech/emailAddress="example@pocketadmin.tech

Generating a 2048 bit RSA private key
..................................................................+++
.+++
writing new private key to 'private.pem'
-----
Subject Attribute TECH has no known NID, skipped

Объявим шифруемую строку и ключи:

$data = 'Эта строка была зашифрована на PHP асимметричным алгоритмом RSA';

$filePublicKey = 'public.crt';
$filePrivateKey = 'private.pem';

Ещё раз хочу обратить внимание, что сам приватный ключ необходимо хранить в тайне! Непосредственно для шифрования третьим лицам достаточно передать только публичный ключ.

Получаем содержимое файла с публичным ключом и извлекаем сам ключ:

$contentsPublicKey = file_get_contents($filePublicKey);
$publicKey  = openssl_get_publickey($contentsPublicKey);

С помощью функции openssl_public_encrypt шифруем данные $data публичным ключом $publicKey. Результат шифрования будет помещен в переменную $encrypted:

openssl_public_encrypt($data, $encrypted, $publicKey);

В дальнейшем, для расшифровки нам понадобится приватный ключ:

$contentsPrivateKey = file_get_contents($filePrivateKey);
$privateKey  = openssl_get_privatekey($contentsPrivateKey);

Чтобы расшифровать данные $encrypted приватным ключом $privateKey воспользуемся функцией openssl_private_decrypt. Результат помещается в переменную $decrypted:

openssl_private_decrypt($encrypted, $decrypted, $privateKey);

Проверим результат с помощью var_dump($decrypted):

string(112) "Эта строка была зашифрована на PHP асимметричным алгоритмом RSA"

Приведем весь код на PHP шифрования данных алгоритмом RSA:

<?php

// Шифруемые данные
$data = 'Эта строка была зашифрована на PHP асимметричным алгоритмом RSA';

// Публичный и приватный ключи шифрования, полученные с помощью openssl
$filePublicKey = 'public.crt';
$filePrivateKey = 'private.pem';

// Извлекаем публичный ключ для шифрования
$contentsPublicKey = file_get_contents($filePublicKey);
$publicKey  = openssl_get_publickey($contentsPublicKey);

// Шифруем данные
openssl_public_encrypt($data, $encrypted, $publicKey);

// Извлекаем приватный ключ
$contentsPrivateKey = file_get_contents($filePrivateKey);
$privateKey  = openssl_get_privatekey($contentsPrivateKey);

// Расшифровываем данные с помощью приватного ключа
openssl_private_decrypt($encrypted, $decrypted, $privateKey);

// Проверяем результат
var_dump($decrypted);

?>

PHP шифрование файлов RSA

Создадим простой текстовый файл, который мы будем шифровать:

$ echo 'Этот файл был зашифрован на PHP асимметричным алгоритмом RSA' > rsa.txt

Используем публичный и приватный ключ из предыдущего примера. Объявим шифруемый файл, шифрованный и расшифрованный:

$filePublicKey = 'public.crt';
$filePrivateKey = 'private.pem';

$file = 'rsa.txt';
$fileEncrypted = 'rsa-encrypted.txt';
$fileDecrypted = 'rsa-decrypted.txt';

По аналогии с предыдущими примерами: получаем публичный ключ $publicKey и с помощью него шифруем содержание файла $file. Результат записываем в $fileEncrypted:

$contentsPublicKey = file_get_contents($filePublicKey);
$publicKey  = openssl_get_publickey($contentsPublicKey);

$contents = file_get_contents($file);
openssl_public_encrypt($contents, $contentsEncrypted, $publicKey);
file_put_contents($fileEncrypted, $contentsEncrypted);

Чтобы расшифровать этот файл: получаем приватный ключ $privateKey, расшифровываем содержимое файла $fileEncrypted. Данные записываем в файл $fileDecrypted:

$contentsPrivateKey = file_get_contents($filePrivateKey);
$privateKey  = openssl_get_privatekey($contentsPrivateKey);

$contentsEncrypted = file_get_contents($fileEncrypted);
openssl_private_decrypt($contentsEncrypted, $contentsDecrypted, $privateKey);
file_put_contents($fileDecrypted, $contentsDecrypted);

Проверим созданный файл:

$ cat rsa-decrypted.txt
Этот файл был зашифрован на PHP асимметричным алгоритмом RSA

Соберем весь код:

<?php

// Объявляем файлы с публичным и приватным ключами
$filePublicKey = 'public.crt';
$filePrivateKey = 'private.pem';

// Объявляем файлы: шифруемый, шифрованный и расшифрованный
$file = 'rsa.txt';
$fileEncrypted = 'rsa-encrypted.txt';
$fileDecrypted = 'rsa-decrypted.txt';

// Получаем публичный ключ из файла
$contentsPublicKey = file_get_contents($filePublicKey);
$publicKey  = openssl_get_publickey($contentsPublicKey);

// Получаем содержимое файла, шифруем его и записываем в новый файл
$contents = file_get_contents($file);
openssl_public_encrypt($contents, $contentsEncrypted, $publicKey);
file_put_contents($fileEncrypted, $contentsEncrypted);

// Получаем приватный ключ из файла
$contentsPrivateKey = file_get_contents($filePrivateKey);
$privateKey  = openssl_get_privatekey($contentsPrivateKey);

// Расшифровываем содержимое шифрованного файла с помощью приватного ключа. Записываем расшифрованный файл
$contentsEncrypted = file_get_contents($fileEncrypted);
openssl_private_decrypt($contentsEncrypted, $contentsDecrypted, $privateKey);
file_put_contents($fileDecrypted, $contentsDecrypted);

?>

Оставьте комментарий