Skip to content

Instantly share code, notes, and snippets.

@XOlegator
Created October 23, 2020 13:33
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save XOlegator/6a193bb9c8a93a9c15b1bc800e9a541b to your computer and use it in GitHub Desktop.
Save XOlegator/6a193bb9c8a93a9c15b1bc800e9a541b to your computer and use it in GitHub Desktop.
Обратимое шифрование: пример функции шифрования и расшифровки
<?php
class Utils
{
/**
* Метод шифрует обратимым методом данные массива.
* Получившаяся строка пригодна для отправки в GET запросе.
*
* @param array $arData Массив данных, который нужно зашифровать
* @param string $encKey Секретный ключ (строка со случайными символами).
*
* @return string Шифрованая строка
*/
public static function encryptArray(array $arData, string $encKey): string
{
$result = '';
if (!empty($arData)) {
// Сериализуем массив
$plaintext = serialize($arData);
$cipher = 'AES-128-CBC';
$ivlen = openssl_cipher_iv_length($cipher);
if (false !== ($iv = openssl_random_pseudo_bytes($ivlen, $isCryptoStrong))
&& false !== $isCryptoStrong
&& $encKey
) {
$ciphertext_raw = openssl_encrypt(
$plaintext,
$cipher,
$encKey,
$options = OPENSSL_RAW_DATA,
$iv
);
$hmac = hash_hmac(
'sha256',
$ciphertext_raw,
$encKey,
$as_binary = true
);
$result = urlencode(
base64_encode($iv . $hmac . $ciphertext_raw)
);
}
}
return $result;
}
/**
* Метод расшифровывает строку
* обратным образом для метода encryptArray()
*
* @param string $str Шифрованая строка
* @param string $encKey Секретный ключ (строка со случайными символами).
*
* @return array Массив данных, который получен при дешифрации
*/
public static function decryptArray(string $str, string $encKey): array
{
$result = [];
if ($str && $encKey) {
$str = urldecode($str);
$c = base64_decode($str);
$cipher = 'AES-128-CBC';
$ivlen = openssl_cipher_iv_length($cipher);
if (function_exists('mb_substr')) {
$iv = mb_substr($c, 0, $ivlen, '8bit');
$hmac = mb_substr($c, $ivlen, $sha2len = 32, '8bit');
$ciphertext_raw = mb_substr($c, $ivlen + $sha2len, mb_strlen($c, '8bit'), '8bit');
} else {
$iv = substr($c, 0, $ivlen);
$hmac = substr($c, $ivlen, $sha2len = 32);
$ciphertext_raw = substr($c, $ivlen + $sha2len);
}
$plaintext = openssl_decrypt(
$ciphertext_raw,
$cipher,
$encKey,
$options = OPENSSL_RAW_DATA,
$iv
);
$calcmac = hash_hmac(
'sha256',
$ciphertext_raw,
$encKey,
$as_binary = true
);
if (hash_equals($hmac, $calcmac)) {
$tmp = unserialize(
$plaintext,
['allowed_classes' => false]
);
if (false !== $tmp) {
$result = $tmp;
}
}
}
return $result;
}
}
// Данные пользователя, которые нужно зашифрованным сообщением переслать на сайт
$arParams = [
'name' => 'subspam@mail.ru',
'password' => '123456789',
'time' => time(), // Подмешиваем что-то, что всегда меняется
];
// Секретный ключ, прописанный в приложении и в настройках сайта
$encKey = '15dbe906c75862983ea410aba4d14c47';
$encString = Utils::encryptArray($arParams, $encKey);
// lx4RMo9MkMbZtgtb7W3C7ka1YKtKfY0t0uIxIeWJCgKkaZZpzinNGBIWmx61airdJlbELKlZSpzlq3Lcyw59b4Bkw8j5QW1JBxq7jNRF2G2z%2Faas4VOLc%2BxLA50E0QU6dViiSsypI20yxJ0UmUYDh2WuBmzt%2BTUwy1yVCI7%2FwOm6N%2FYczsTig63aOQ8jL9dl
echo '<pre>$encString = ';
print_r($encString);
echo '</pre>';
// Расшифруем полученную пользовательскую нагрузку
$arDecryptParams = Utils::decryptArray($encString, $encKey);
// Array
//(
// [name] => subspam@mail.ru
// [password] => 123456789
// [time] => 1603459617
//)
echo '<pre>1. $arDecryptParams = ';
print_r($arDecryptParams);
echo '</pre>';
if (empty($arDecryptParams)) {
// Параметры могут приходить по-разному:
// url-кодированые или не кодированые.
// Проверяем оба варианта
$arDecryptParams = Utils::decryptArray(
urlencode($arDecryptParams),
$encKey
);
echo '<pre>2. $arDecryptParams = ';
print_r($arDecryptParams);
echo '</pre>';
}
if (!empty($arParams['name']) && !empty($arParams['password'])) {
echo '<pre>Удалось расшифровать нагрузку: это запрос от разрешённого приложения</pre>';
} else {
echo '<pre>Не удалось расшифровать нагрузку: это недопустимое обращение к API</pre>';
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment