遇到PHP请求Java的接口,返回的数据是以SM4/ECB/PKCS5Padding的对称加密方式加密后的密文。网上搜索别人早期写的大部分代码类单纯是针对国密SM4算法本身的加解密处理,未能涉及到ECB等加密模式。
前期找到https://github.com/lpilp/phpsm2sm3sm4项目,里面支持sm4-ecb的加解密模式,里面sm4的对称加解密,要求PHP版本>=PHP7.2,且需打开gmp的扩展支持。在服务器上编译引入gmp扩展之后,通过composer require lpilp/guomi命令安装,发现安装不了还是提示未找到gmp的扩展,使用不同服务器再次尝试还是一样问题,遂放弃了该项目仓库。
最后采用了另一种方式,利用openssl 1.1.1x后的版本,其支持了sm4-ecb模式,通过PHP的openssl扩展openssl_decrypt函数进行解密,它默认的填充方式为PKCS7Padding,PKCS5Padding是PKCS7Padding的子集,对应使用方式一样默认可以解析:
$res = openssl_decrypt($ciphertext,'sm4-ecb',$key,OPENSSL_RAW_DATA,$iv);
其中,$ciphertext为将密文进行base64url_decode处理之后的字符串,$key为Java方提供的对称加密密钥,期间使用该函数调试,发现死活没法解密出明文。尝试多种方式未能成功的情况下,查看php官方的openssl_decrypt函数说明文档:PHP: openssl_decrypt - Manual PHP中文手册 PHP中国镜像 php 国内镜像 PHP官方网站
在里面看到针对$key有进行hen2bin的处理:
添加该处理方式之后,终于成功解密出明文。
最终代码如下:
function base64url_decode($data) {//该函数将RFC4648 URL安全Base64变体(RFC4648_URLSAFE)转换为Base64,然后再base64_decode转换为明文
return base64_decode(str_pad(strtr($data,'-_','+/'),strlen($data) % 4,'=',STR_PAD_BOTH));//STR_PAD_RIGHT
}
$res = base64url_decode($res);
$cipher = 'sm4-ecb';
$iv = '';
$original_plaintext = openssl_decrypt($res,$cipher,hex2bin($this->data["appKey"]),$iv);
原文地址:https://blog.csdn.net/lvsos/article/details/132898881
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。