当前位置: 首页 > news >正文

PHP如何解决使用国密SM4解密Base64数据错误问题?(基于lpilp/guomi)

最近遇到与java对接的时候接收的base64数据,SM4解密一部分正常、一部分乱码乱码的问题,最后仔细看了接收到的base64数据,发现是PHP接收url中的数据问题。

一、下面展示下解决问题之前的问题:

首先、把需要加密的json串整理出来,进行SM4加密

其次、将加密后的base64串添加到接口请求工具中data参数值中

再次、打印PHP接收到的base64数据串

最后、用接收到的数据串进行SM4解密,打印出来发现只解析了前面一点点,后面的是乱码

解决思路:

重点在以下几点:

1、接收到的base64数据;

2、lpilp/guomi扩展包中的SM4加密解密的方法;

思考:扩展包的加密解密方法肯定是没问题的,但是也不保证没有问题,细扒代码,发现是在解密base64_decode数据后,用解密方法解出来后就有问题了,解密方法之前用过,可以肯定没有问题,那就是传入的解密数据有问题了。

发现问题:仔细一看打印出来的加密后的数据和PHP接收到的数据不一样,接收到的数据中有空格。

原因是:+号在 URL 中被浏览器/前端自动转换成空格(空格编码成 %20),而后端 request()->all() 又把空格保留下来,最终造成 Base64 字符串被破坏。

解决办法:将接收到的数据中的空格转换成+号还原。再去调用解密方法

$cipher = str_replace(' ', '+', $cipher);   // 把空格全部还原成 +
$plain  = (new RtSm4($key))->decrypt($cipher, 'sm4-ecb', '', 'base64');

将数据顺利解密,出来的结果如下:

与加密数据一致。

附件:SM4和SM2加密解密的公共调用方法

<?phpnamespace App\Support;
use Rtgm\sm\RtSm4;
use Rtgm\sm\RtSm2;
use Rtgm\util\MyAsn1;class GuomiHelper
{/*** 生成安全随机数(不超过128位)** @param int $length 随机数长度,最大128位* @return string*/public static function generateNonce($length = 32){$length = min($length, 128);$bytes = random_bytes(ceil($length / 2));return substr(bin2hex($bytes), 0, $length);}/*** 使用 key 进行 SM4 ECB 加密(在用)** @param string $data* @param string $key* @return string*/public static function sm4EcbEncrypt($data, $key) {//dump($data);// 使用示例// $key = hex2bin("30ca0d013a9a782fe4c6b4c30d3e208c");// $data = "18900112233"; 运行结果;571d9decc557bd9d466f6c90df328bb4$key = hex2bin($key);//将十六进制字符串转换为二进制数据$sm4 = new RtSm4($key);$ciphertext = $sm4->encrypt($data, 'sm4-ecb','','base64');return $ciphertext;}/*** 使用 key 进行 SM4 ECB 解密(在用)* * @param string $data* @param string $key* @return string*/public static function sm4EcbDecrypt($data, $key) {// 移除base64编码中的空格换行$key = hex2bin($key);//将十六进制字符串转换为二进制数据 $data, $type = 'sm4', $iv = '', $formatInput = 'hex'$sm4 = new RtSm4($key);$plaintext = $sm4->decrypt($data, 'sm4-ecb','','base64');return $plaintext;}/*** 账户公钥SM2加密(在用)** @param string $data* @param string $publicKey* @return string*/public static function rtSm2Encrypt($plaintext, $publicKeyBase64) {    // 从DER格式中提取公钥内容(去除ASN.1头部)$publicKeyHex =  MyAsn1::decode($publicKeyBase64,'base64');// 创建SM2实例$sm2 = new RtSm2();// 执行加密(使用公钥的十六进制格式)$ciphertextBin = $sm2->doEncrypt($plaintext, $publicKeyHex[1]);return '04'.$ciphertextBin;}/*** 账户私钥SM2解密(在用)*/public static function rtSm2Decrypt($ciphertext, $privateKey) {// 创建SM2实例$sm2 = new RtSm2();$m2DecryptData = $sm2->doDecrypt($ciphertext,$privateKey);return $m2DecryptData;}/*** 账户公钥SM2验签* 使用 SM2 非对称加密算法结合 SM3 哈希算法对给定的数据进行签名验证* @param string $publicKeyString:十六进制字符串表示的 SM2 公钥。* @param string $notifyString:需要验证签名的原始数据字符串。* @param string $signString:十六进制字符串表示的签名数据。* @return string*/public static function sm2WithSM3Verify($publicKeyString, $notifyString, $signString){$sm2 = new RtSm2();$result = $sm2->verifySign($notifyString, $signString, $publicKeyString);return $result;}
}


文章转载自:

http://POvlU4i2.mxxsq.cn
http://Ykfwu6Zj.mxxsq.cn
http://oioCvZdI.mxxsq.cn
http://iIqGvXCT.mxxsq.cn
http://xGGac2K9.mxxsq.cn
http://IUKhhVRR.mxxsq.cn
http://oOoIhWWq.mxxsq.cn
http://0rQaoneb.mxxsq.cn
http://A9OZTMEw.mxxsq.cn
http://pXtXx5zB.mxxsq.cn
http://x4X53Pgn.mxxsq.cn
http://cfcR2hPF.mxxsq.cn
http://dMDbfbda.mxxsq.cn
http://HYQ6wteQ.mxxsq.cn
http://Jur1lnZA.mxxsq.cn
http://Qk9eFX6t.mxxsq.cn
http://UeKs7Gde.mxxsq.cn
http://pRa9aQKw.mxxsq.cn
http://KAbSv3gJ.mxxsq.cn
http://TDhZX1AD.mxxsq.cn
http://6qkSQL7v.mxxsq.cn
http://fJfwn41T.mxxsq.cn
http://0r2wlJtH.mxxsq.cn
http://DTeyJ1JC.mxxsq.cn
http://EbFDchAW.mxxsq.cn
http://FBUpBXR8.mxxsq.cn
http://8aCh9Off.mxxsq.cn
http://7WwKOHNq.mxxsq.cn
http://cJ3zsw61.mxxsq.cn
http://E3XeEuS0.mxxsq.cn
http://www.dtcms.com/a/365129.html

相关文章:

  • [论文阅读] 人工智能 + 软件工程 | ReCode:解决LLM代码修复“贵又慢”!细粒度检索+真实基准让修复准确率飙升
  • 一键 i18n 国际化神库!适配 Vue、React!
  • CMake构建学习笔记24-使用通用脚本构建PROJ和GEOS
  • Web端最强中继器表格元件库来了!55页高保真交互案例,Axure 9/10/11通用
  • Java学习笔记-零基础学MySQL(四)
  • 三阶Bezier曲线,已知曲线上一点到曲线起点的距离为L,计算这个点的参数u的方法
  • 【C++】C++入门—(中)
  • MySQL 开发避坑:DROP TABLE 前你必须知道的几件事
  • 【题解】洛谷P1776 宝物筛选 [单调队列优化多重背包]
  • 2.插值法
  • 【C++】深入浅出:string类模拟实现全解析
  • maven scope=provided || optional=true会打包到jar文件中吗?
  • 资产管理还靠Excel?深度体验系统如何让企业高效数字化升级!
  • 机器学习从入门到精通 - 机器学习调参终极手册:网格搜索、贝叶斯优化实战
  • CVE-2025-6507(CVSS 9.8):H2O-3严重漏洞威胁机器学习安全
  • net9 aspose.cell 自定义公式AbstractCalculationEngine,带超链接excel转html后背景色丢失
  • 原创未发表!POD-PINN本征正交分解结合物理信息神经网络多变量回归预测模型,Matlab实现
  • LightDock:高效蛋白质-DNA对接框架
  • 小白成长之路-develops -jenkins部署lnmp平台
  • GPT在嵌入式代码设计与硬件PCB设计中的具体应用
  • Git或TortoiseGit的小BUG(可解决):空库报错Could not get hash of ““
  • Android Handler 消息循环机制
  • Python基础(⑨Celery 分布式任务队列)
  • 【计算机科学与应用】基于FME的自动化数据库建设方法及应用实践
  • 产线自动化效率上不去?打破设备和平台的“数据孤岛”是关键!
  • R-4B: 通过双模退火与强化学习激励多模态大语言模型的通用自主思考能力
  • 简单工厂模式(Simple Factory Pattern)​​ 详解
  • Java中最常用的设计模式
  • 【设计模式】 装饰模式
  • 游戏世代网页官网入口 - 游戏历史记录和统计工具