wub*_*ube 6 php encryption aes encryption-symmetric php-openssl
这是我用来加密/解密数据的代码:
// Set the method
$method = 'AES-128-CBC';
// Set the encryption key
$encryption_key = 'myencryptionkey';
// Generet a random initialisation vector
$iv = openssl_random_pseudo_bytes(openssl_cipher_iv_length($method));
// Define the date to be encrypted
$data = "Encrypt me, please!";
var_dump("Before encryption: $data");
// Encrypt the data
$encrypted = openssl_encrypt($data, $method, $encryption_key, 0, $iv);
var_dump("Encrypted: ${encrypted}");
// Append the vector at the end of the encrypted string
$encrypted = $encrypted . ':' . $iv;
// Explode the string using the `:` separator.
$parts = explode(':', $encrypted);
// Decrypt the data
$decrypted = openssl_decrypt($parts[0], $method, $encryption_key, 0, $parts[1]);
var_dump("Decrypted: ${decrypted}");
Run Code Online (Sandbox Code Playgroud)
它ususaly工作正常,但有时(十分之一,甚至更少)它失败.如果失败,则文本仅部分加密:
这是发生时的错误消息:
Warning: openssl_decrypt(): IV passed is only 10 bytes long, cipher expects an IV of precisely 16 bytes, padding with \0
Run Code Online (Sandbox Code Playgroud)
当它发生时,加密文本看起来像:
Encrypt me???L?se!
Run Code Online (Sandbox Code Playgroud)
我认为它可能是由PHP中的错误引起的,但我已经在不同的主机上测试过:PHP 7.0.6和PHP 5.6.我也尝试了多个在线PHP解析器,如phpfidle.org或3v4l.org.
似乎openssl_random_pseudo_bytes并不总是返回一个适当长度的字符串,但我不知道为什么.
以下是示例:https://3v4l.org/RZV8d
继续刷新页面,你会在某些时候得到错误.
Sco*_*ski 12
当您生成随机IV时,您将获得原始二进制文件.二进制字符串将包含一个:或一个\0字符的非零机会,您将其用于将IV与密文分开.这样做可以explode()为您提供更短的字符串.演示:https://3v4l.org/3ObfJ
简单的解决方案是将base64编码/解码添加到此过程.
也就是说,请不要滚动自己的加密.特别是,未经身份验证的加密是危险的,并且已经存在可以解决此问题的安全库.
不要自己编写,而是考虑使用defuse/php-encryption.这是安全的选择.