
国密算法(SM2/SM4)在金融领域的应用背景
银行系统对数据加密的合规性要求(如《金融数据安全指南》)
PHP生态中国密算法支持的现状与挑战
与银行对接支付需要给敏感字段加密,比如手机号、姓名、卡号等敏感信息,银行给的文档上明确需要将敏感字段加密,了解完需求后下面开始编程阶段了。
第一步、环境准备与依赖库
PHP版本要求(建议7.4+),支持openssl扩展。
安装lpilp/guomi扩展的步骤(***poser)
命令: ***poser require lpilp/guomi
依赖库的兼容性检查(OpenSSL版本等)
等待安装,看到如下截图,说明安装成功。
第二步、系统中引入vender包中的扩展程序
第三步、查看vender包中的readme文件,查看示例,根据示例实现加密程序
1、根据公钥实现SM4非对称加密
/**
* 账户公钥SM2加密(在用)
*
* @param string $data
* @param string $publicKey
* @return string
*/
public static function Sm2Encrypt($plaintext, $publicKeyBase64)
{
//银行给的公钥类似于下面这样的 Base64格式的串
// $publicKeyBase64 = 'JGFwEwYHKoZIzj0CAQYIKoEcz1UBg40TggAEPUE5W9fRgSP2SMEkztigKvsvZj+vaDq5Tyo1T5sfdJ/4olg/o3SjET3sfpX4yS5aJprh5RhybTJXVKTzUJILFg==';
// 从DER格式中提取公钥内容(去除ASN.1头部)
$publicKeyHex = MyAsn1::decode($publicKeyBase64,'base64');
// 创建SM2实例
$sm2 = new RtSm2();
// 执行加密(使用公钥的十六进制格式)
$ciphertextBin = $sm2->doEncrypt($plaintext, $publicKeyHex[1]);
return '04'.$ciphertextBin;
}
2、根据key实现SM4对称加密
首先生成16进制的随机字符串,生成后是这样的:20ca1d513a9a594fe4c6b4c30d3e907c
/**
* 生成一个指定长度的16进制随机字符串
* @param int $length 字符串长度(默认32位)
* @return string
*/
public function generateNonce($length = 32)
{
$length = min($length, 128);
$bytes = random_bytes(ceil($length / 2));
return substr(bin2hex($bytes), 0, $length);
}
生成后,使用这个作为key,进行加密 ,返回加密数据
/**
* 使用 key 进行 SM4 ECB 加密(在用)
*
* @param string $data
* @param string $key
* @return string
*/
public static function sm4Encrypt($data, $key)
{
// 使用示例
// $key = hex2bin("30ca0d013a9a782fe4c6b4c30d3e208c");
// $data = "18900112233"; 运行结果;571d9de***557bd9d466f6c90df328bb4
$key = hex2bin($key);//将十六进制字符串转换为二进制数据
$sm4 = new RtSm4($key);
$ciphertext = $sm4->encrypt($data, 'sm4-ecb');
return $ciphertext;
}
错误处理:
1、如果执行***poser命令出现如下错误:
意思是让你检查你的php.ini,看看有没有安装gmp,根据提示去查看
查看命令:php --ini
发现确实没有gmp扩展,下面进行安装gmp
centos9安装命令: sudo yum install gmp-devel
等一会安装完后出现版本号信息,这个说明安装成功,下面重启PHP服务
重启命令:sudo service php-fpm restart
重启后再执行: php --ini
看到有gmp,说明安装成功
还可以通过:php -m 命令查看