PHP7以后,不再支持mcrypt扩展,被OpenSSL扩展所替代。简单介绍一下PHP中OpenSSL 扩展的DES对称加密。
DES对称加密,全称为 Data Encryption Standard 是一种比较传统的加密方式,其加密运算、解密运算使用的是同样的密钥,信息的发送者和信息的接收者在进行信息的传输与处理时,必须共同持有该密码(称为对称密码)。
DES对称加密密钥长度是64位(bit),超过位数密钥被忽略。对称性加密一般会按照固定长度,把待加密字符串分成块,不足一整块或者刚好最后有特殊填充字符。
首先看下PHP中OpenSSL扩展对称加密的相关函数有:
openssl_encrypt()
说明:以指定的方式和 key 加密数据,返回原始或 base64 编码后的字符串。
格式:openssl_encrypt ($data, $method, $password, $iv);
参数:
1、$data(string)待加密的明文信息数据;
2、$method(string)密码方式(通过openssl_get_cipher_methods()获取)。
3、$password(string)加密密钥[密码]
4、$options(int)数据格式选项(可选)0、OPENSSL_RAW_DATA=1、OPENSSL_ZERO_PADDING=2、OPENSSL_NO_PADDING=3
5、$iv(非 NULL 的初始化向量)(可选,$method为DES−ECB方式是可以不用填写,其他的必须)
返回值:字符串(string)
openssl_decrypt()
说明:采用原始或base64编码的字符串,并使用给定的方法和密钥对其进行解密。
格式:openssl_decrypt ($data, $method, $password, $iv);
参数:$data(string)待解密的明文信息数据;其他参数和openssl_encrypt参数一致。
返回值:字符串(string)
openssl_random_pseudo_bytes()
说明:生成一个伪随机字节字符串
格式:openssl_random_pseudo_bytes ($length, $crypto_strong);
参数:1、$length(int)所需字节字符串的长度。必须是正整数。PHP将尝试将此参数转换为非空整数来使用它。
2、$crypto_strong(bool)该值确定所使用的算法是否“密码强”,TRUE是,否则FALSE。
返回值:字符串(string)
openssl_get_cipher_methods()
说明:获取可用的加密算法的列表。
格式:openssl_get_cipher_methods ($aliases);
参数:$aliases(bool)[默认值false]如果密码别名应该包含在返回的array中,则设置为 TRUE.
返回值:数组(array)
openssl_cipher_iv_length()
说明:获取密码iv长度。
格式:openssl_cipher_iv_length ($method);
参数:$method(string)密码方法,见openssl_get_cipher_methods()有关潜在值的列表。
返回值:整数(int)
简单示例:
<?php
// 获取可用的加密算法的列表。
$list = openssl_get_cipher_methods();
print_r($list);
echo '<br>';
// openssl_get_cipher_methods列表提供的加密算法
$encryptMethod = 'AES-128-ECB';
// 明文数据
$data = 'Hello World';
// 加密
$encrypted = openssl_encrypt($data, $encryptMethod, 'secret',0);
echo $encrypted; // Ye4LKyGwPlf1zcSKjeSbiQ==
echo '<br>';
// 解密
$decrypted = openssl_decrypt($encrypted, $encryptMethod, 'secret',0);
echo $decrypted; // Hello World
?>
试用生成IV进行加密示例:
<?php
$encryptMethod = 'AES-128-CBC';
// 明文数据
$data = 'Hello World';
// 生成IV
$ivLength = openssl_cipher_iv_length($encryptMethod); //16
$iv = openssl_random_pseudo_bytes($ivLength, $isStrong);
if (false === $iv && false === $isStrong) {
die('IV generate failed');
}
// 加密
echo $encrypted = openssl_encrypt($data, $encryptMethod, 'secret', 0, $iv);
echo '<br>';
// 解密
echo $decrypted = openssl_decrypt($encrypted, $encryptMethod, 'secret', 0, $iv);
?>
IV 初始化向量:在CBC模式的加密算法中,以组为单位加密明文会被分成若干个组,每个组的加密过程,依赖他前一个组的数据成本组的密文。最开头的那个组又要依赖IV。IV是随机生成,通过 openssl_random_pseudo_bytes()函数生成IV的长度。使用 openssl_cipher_iv_length() 函数获得加密算法需要的IV长度。
例如:
<?php
echo openssl_cipher_iv_length('AES-256-CBC'); // 16
echo openssl_cipher_iv_length('BC-CBC'); // 8
echo openssl_cipher_iv_length('AES-128-ECB'); // 0
?>
需要注意:
1、如果为DES−ECB时,不需要 IV,所以ECB这种通过openssl_cipher_iv_length获得的长度为0。
2、当加密算法为其他时必须传$iv参数,不传报错一个Warning错误。
3、IV应该是随机生成的用openssl_random_pseudo_bytes(),不能人为编写。
4、每次加密都应该重新生成一次IV ,不要多次加密采用相同IV
5、IV要随着密文一起保存用作下次解密,不然就没法解密了。