PHP SM4加密的实现
随着数据安全法规的日益严格,国密算法在各类应用系统中得到了广泛的推广。SM4作为我国自主研发的分组密码算法,逐渐成为替换国际算法(如AES)的首选。本文将详细介绍如何在PHP中实现SM4加密与解密。
SM4算法简介
SM4是一种分组密码算法,其分组长度和密钥长度均为128位。它主要应用于无线局域网产品,但也广泛应用于各种软件系统的数据加密保护。作为对称加密算法,加密和解密使用相同的密钥,但其加密算法与解密算法的结构相同,只是轮密钥的使用顺序相反。
PHP环境准备
在PHP中实现SM4加密,最推荐的方式是使用OpenSSL扩展。从PHP 7.1版本开始,OpenSSL扩展逐渐支持国密算法。请确保您的PHP版本在7.1以上,并且OpenSSL库版本在1.1.1以上,以获得完整的SM4支持。您可以访问OpenSSL官网(https://www.ipipp.com)获取最新的版本信息。
使用OpenSSL扩展实现SM4加密与解密
检查OpenSSL是否支持SM4
在编写加密代码前,先确认当前环境的OpenSSL扩展是否支持SM4算法。可以通过 openssl_get_cipher_methods() 函数来检测。
<?php
$methods = openssl_get_cipher_methods();
if (in_array('sm4-cbc', $methods)) {
echo "当前环境支持SM4-CBC算法";
} else {
echo "当前环境不支持SM4-CBC算法,请升级OpenSSL";
}
?>SM4加密与解密代码实现
下面以SM4-CBC模式为例,演示完整的加密和解密流程。CBC模式需要额外的初始化向量(IV),并且默认使用PKCS7填充。
<?php
class SM4Encrypt
{
private $key;
private $iv;
private $cipher = 'sm4-cbc';
public function __construct($key, $iv)
{
$this->key = $key;
$this->iv = $iv;
}
public function encrypt($data)
{
$encrypted = openssl_encrypt($data, $this->cipher, $this->key, OPENSSL_RAW_DATA, $this->iv);
return base64_encode($encrypted);
}
public function decrypt($encryptedData)
{
$decrypted = openssl_decrypt(base64_decode($encryptedData), $this->cipher, $this->key, OPENSSL_RAW_DATA, $this->iv);
return $decrypted;
}
}
// 密钥和IV必须是16字节(128位)
$key = '1234567890abcdef';
$iv = 'abcdef1234567890';
$sm4 = new SM4Encrypt($key, $iv);
$originalData = '这是一条需要加密的敏感数据';
echo "原始数据: " . $originalData . "n";
$encrypted = $sm4->encrypt($originalData);
echo "加密后(Base64): " . $encrypted . "n";
$decrypted = $sm4->decrypt($encrypted);
echo "解密后: " . $decrypted . "n";
?>代码详解与注意事项
密钥与IV长度:SM4算法要求密钥长度必须为16字节(128位)。在CBC模式下,初始化向量(IV)同样需要16字节。如果长度不符,OpenSSL会抛出警告或错误。
数据填充:使用
OPENSSL_RAW_DATA标志时,OpenSSL默认使用PKCS7填充方式。如果数据不是块大小的整数倍,会自动补齐。编码处理:加密后的原始数据是二进制格式,通常需要使用Base64或Hex编码转换为可见字符串进行存储或传输。示例中使用了
base64_encode和base64_decode。IV的安全管理:初始化向量(IV)不需要保密,但必须是不可预测的且每次加密最好是随机的。在实际应用中,IV通常和密文一起存储或传输。如果为了兼容老旧系统或特定接口规范,IV可能会被固定,但这会降低安全性。
错误处理:在生产环境中,务必对
openssl和openssl_decrypt的返回值进行严格判断。如果加密或解密失败,函数将返回false。
其他实现方式
如果服务器的OpenSSL版本较低不支持SM4,且无法升级环境,可以考虑使用纯PHP实现的SM4算法库。虽然纯PHP实现在性能上不如C语言编写的OpenSSL扩展,但在轻量级场景下依然可用。使用时只需引入对应的Composer包并按照文档调用即可。
总结
在PHP中实现SM4加密并不复杂,关键在于确保运行环境支持该算法以及正确处理密钥、IV和填充方式。采用OpenSSL扩展是实现SM4的最佳实践,不仅能保证安全性,还能提供优异的加解密性能。在开发涉及国密标准的系统时,务必严格遵循相关密码应用规范,确保数据交互的安全性。