Я пытаюсь зашифровать / расшифровать некоторые данные с помощью openssl_encrypt / openssl_decrypt. Цель заключается в следующем: пользователь вводит некоторые данные в графический интерфейс, эти данные шифруются и хранятся в базе данных. Позже он будет извлечен и расшифрован только для определенного профиля пользователя.
Зашифрованная часть работает нормально, так как я последовал совету коллеги, которая заключает вывод в функцию bin2hex.
Все дело в том, что я не могу получить двоичный вывод при расшифровке данных, даже если я пытаюсь преобразовать вывод, используя hex2bin. Я всегда получаю вывод типа «» Ps 1 _G 5 OUT ».
У меня заканчиваются идеи, на самом деле я действительно не знаю, что делать в этот момент.
Это пример кода, который я написал для проверки этих функций:
PHP
function encrypt($string) {
$cypher = 'aes-256-cbc';
$key = 's7aBkf4Ypn59bWviQziPDXyPasdaYlhQ';
$ivsize = openssl_cipher_iv_length($cypher);
$iv = openssl_random_pseudo_bytes($ivsize);
$encripted = openssl_encrypt(
$string, $cypher, $key, OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING, $iv
);
return $iv . $encripted;
}
function decrypt($string) {
$cypher = 'aes-256-cbc';
$key = 's7aBkf4Ypn59bWviQziPDXyPasdaYlhQ';
$ivsize = openssl_cipher_iv_length($cypher);
$iv = mb_substr($string, 0, $ivsize, '8bit');
$decrypted = mb_substr($string, $ivsize, null, '8bit');
$output = openssl_decrypt(
$decrypted, $cifrado, $key, OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING, $iv
);
return $output;
}
HTML:
<!doctype html>
<html>
<head><title>TEST</title></head>
<body>
<div style='margin-left:250px;'>
<form action="test.php" method="POST">
Encrypt
<input type="text" name="encrypt" value=''/>
<input type="submit" name="send" value='Send'/>
<br/><br/>
<?php
if (isset($_POST['encrypt']) && !empty($_POST['encrypt'])) {
echo 'encrypted string: ' . bin2hex(encrypt($_POST['encrypt']));
}
?>
<br/>
<br/>
Decrypt
<input type="text" name="decrypt" value=''/>
<input type="submit" name="send" value='Send'/>
<br/><br/>
<?php
if (isset($_POST['decrypt']) && !empty($_POST['decrypt'])) {
echo 'decrypted string: ' . decrypt($_POST['decrypt']);
var_dump(decrypt($_POST['decrypt']));
}
?>
</form>
</body>
Любые идеи или помощь будут оценены.
Моя версия PHP 5.4.45-0 + deb7u2.
Заранее спасибо.
Обновлено в соответствии с замечаниями @Zaph.
Произошла небольшая синтаксическая ошибка. Однако проблема с кодом заключается в том, что в процедуре шифрования нам разрешено только одно из: OPENSSL_RAW_DATA или OPENSSL_ZERO_PADDING. Это упоминается в документации.
Комментарии от @Zaph: PKCS # 7 padding, который является общим padding, должен использоваться. Оказывается, по умолчанию для PHP OpenSSL используется PKCS # 7. Таким образом, не добавляйте никакой опции заполнения, и вы получите правильную вещь.
Openssl_encrypt()
добавляет заполнение PKCS7 в открытый текст перед шифрованием блочным шифром в режиме CBC или ECB. Openssl_decrypt()
удаляет отступ после расшифровки
Я использую PHP 5.4.4.
Итак, единственная необходимая опция была: OPENSSL_RAW_DATA.
Чтобы обеспечить безопасное хранение зашифрованной строки в любом месте. я имею base64_encoded
Это.
Демонстрация в: ideone.com
/**
* Encrypt a string
*
*
* @Param string $data
* @Param string $key
*
* @return string - base64_encoded
*/
function encrypt($data, $key) {
$cypher = 'aes-256-cbc';
$ivSize = openssl_cipher_iv_length($cypher);
$ivData = openssl_random_pseudo_bytes($ivSize);
$encripted = openssl_encrypt($data,
$cypher,
$key,
OPENSSL_RAW_DATA,
$ivData);return base64_encode($ivData . $encripted);
}
/**
* Decrypt a string
*
* @Param string $data
* @Param string $key
*
* @return string - original text
*/
function decrypt($data, $key) {
$cypher = 'aes-256-cbc';
$ivSize = openssl_cipher_iv_length($cypher);
$data = base64_decode($data);
$ivData = substr($data, 0, $ivSize);
$encData = substr($data, $ivSize);
$output = openssl_decrypt($encData,
$cypher,
$key,
OPENSSL_RAW_DATA,
$ivData);
return $output;
}
$srcText = "Hello World! - " . uniqid();
$key = 's7aBkf4Ypn59bWviQziPDXyPasdaYlhQ';
$srcEncrypted = '';
$srcDecrypted = '';
$srcEncrypted = encrypt($srcText, $key);
$srcDecrypted = decrypt($srcEncrypted, $key);
var_dump($srcText,
$srcEncrypted,
$srcDecrypted,
$srcDecrypted == $srcText);
string 'Hello World! - 5776adf944c52' (length=28)
string 'NOjIIMM0visDbJPmBsAMgH+OQbYiReLBSvzg5JVZTMUOCAtk3CO7FBNs/Dn/vE9s' (length=64)
string 'Hello World! - 5776adf944c52' (length=28)
boolean true
Других решений пока нет …