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 битным ключом:
Все доступные методы шифрования можно посмотреть следующим образом:
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= (opens in a new tab)" rel="noreferrer noopener" href="https://www.php.net/manual/ru/function.openssl-decrypt.php" target="_blank">openssl_decrypt: $decrypted = openssl_decrypt($encrypted, $method, $key);
Опять воспользуемся var_dump($decrypted):
string(107) "Это строка была закодирована симметричным шифрованием AES"
Конечный листинг примера симметричного шифрования/расшифровки данных на PHP будет следующий:
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:
Асимметричное шифрование
Асимметричное шифрование отличается от симметричного тем, что для шифровки и расшифровки данных используется не один общий ключ, а два разных. Одним из самых распространенных алгоритмов асимметричного шифрования является 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 wp-block-code">$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 шифрование файлов 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