求助,和java对接国密sm2签名和验证不通过

代码

  • 用的安装包
    composer require lpilp/guomi
  • PHP代码
    $sm2 = new RtSm2('hex', false);
    // 公钥
    $publicKey = 'xxxxxxxxxxxxxxxxxxxxxx';
    // 私钥
    $privateKey = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxx';
    $userId = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx';
    $data = '{"dateStart":"2023-03-29 00:00:00","dateEnd":"2023-03-30 00:00:00","orgId":"390912547139825664"}20230327143500';
    $sign = $sm2 ->doSign($data, $privateKey, $userId);
    //验签
    $m2SignVerify = $sm2->verifySign($data, $sign, $publicKey, $userId);
  • java同事的代码

    遇到的问题

    用php和java最初生成的签名长度都是70或者71,对接签名验证不通过
    我这边的java同事加了sm2.usePLainEncoding(),设置了PLainDSAEncoding编码后签名长度固定为64,和第三方的java签名验证通过
    应该问题就差在这个编码,所以用php如何生成长度为64位的签名?
    php始终是验证不通过,跪求PHP如何设置这个编码?
    我又尝试安装了GmSSL-PHP这个扩展,签名结果和lpilp/guomi是一致的,长度也是70位,互相验签能通过。但是和java对接就是验证不通过
    总感觉就差一点点,就是没找见原因,又遇到过的大佬还望指点!
    我就想知道php差哪了,欢迎研究,转发分享,用php生成的签名能验证通过的,我管他叫大哥,咋的都行:pray:

    测试数据

    验证工具网址
    私钥:24EE8C7931D7031E90A032ADB16CB31DD33F74E99A595823E7571C66D8287816
    公钥:7FF1D10F4DDF67F9147B820900B4EDD915B65F8614D88DB02CFDDCEEEDE7A58B17118400DD172D2FCE8BC16E601455E2BFEA4E0553964FD1293B8CC18B66335D
    UserID:31323334353637383132333435363738
    数据格式:选择ASC格式
    签名的数据:12345678
    验证方式:把生成的签名放在网站最下面签名后的数据里面,点公钥验签,显示通过为验证成功
《L04 微信小程序从零到发布》
从小程序个人账户申请开始,带你一步步进行开发一个微信小程序,直到提交微信控制台上线发布。
《G01 Go 实战入门》
从零开始带你一步步开发一个 Go 博客项目,让你在最短的时间内学会使用 Go 进行编码。项目结构很大程度上参考了 Laravel。
最佳答案

@deatil 你这个签名是composer require lpilp/guomi这个包生成的吗,这个确实能验证通过,另外方便看下你的$sign咋生成的吗,和我的方法不一样吗。我生成的验证不通过那

f7bc8e4e12eeb381688c579817939e9706cd6c3768a0b8e1e4e014db2efcc67cab9fc94879f68fadc23b3b9a84522d3bef9faf1deb57f601f080c33c31f8cd37

我的代码

use Rtgm\sm\RtSm2;
use Rtgm\util\SmSignFormatRS;

$sm2 = new RtSm2('hex', false);
$document = '12345678';
echo "原始: $document"."<hr>";
$publicKey = '7FF1D10F4DDF67F9147B820900B4EDD915B65F8614D88DB02CFDDCEEEDE7A58B17118400DD172D2FCE8BC16E601455E2BFEA4E0553964FD1293B8CC18B66335D';
// 私钥
$privateKey = '24EE8C7931D7031E90A032ADB16CB31DD33F74E99A595823E7571C66D8287816';
$userId = '31323334353637383132333435363738';
$m2SignData = $sm2 ->doSign($document, $privateKey, $userId);
$res = SmSignFormatRS::asn1_to_rs($m2SignData, "hex");
$res = bin2hex(base64_decode($res));
echo '原始签名';
var_dump($m2SignData);
echo '<hr>';
echo ("处理后: ");
var_dump($res);

原始签名string(140) "304402205fa066ce9671d5fd5c309896f72f8a5b8908e0c06da77c1440fcb770373c13500220658ba0ce573231cb3e9862f5b2d1956b4fe9689e58d1994585eb893e37562d00"
处理后: string(128) "5fa066ce9671d5fd5c309896f72f8a5b8908e0c06da77c1440fcb770373c1350658ba0ce573231cb3e9862f5b2d1956b4fe9689e58d1994585eb893e37562d00"
8个月前 评论
deatil 8个月前
deatil 8个月前
小狼 (作者) (楼主) 8个月前
Potato1 5个月前
deatil 5个月前
deatil 5个月前
Potato1 5个月前
deatil 5个月前
Potato1 5个月前
deatil 5个月前
Potato1 5个月前
deatil 5个月前
Potato1 5个月前
Potato1 5个月前
deatil 5个月前
Potato1 5个月前
讨论数量: 40
随波逐流

没有对接过,都试试吧

blog.csdn.net/qq_19289995/article/...

8个月前 评论
小狼 (楼主) 8个月前

github.com/lpilp/phpsm2sm3sm4/blob...
用库带的方法转换下。
看起来跟招行的有些类似,签名数据也可以用
github.com/lpilp/phpsm2sm3sm4/blob... 这个处理试下

8个月前 评论
小狼 (楼主) 8个月前
deatil (作者) 8个月前
deatil (作者) 8个月前
deatil (作者) 8个月前
小狼 (楼主) 8个月前
deatil (作者) 8个月前
deatil (作者) 8个月前
小狼 (楼主) 8个月前
deatil (作者) 8个月前
小狼 (楼主) 8个月前
deatil (作者) 8个月前
deatil (作者) 8个月前
deatil (作者) 8个月前

直接调用JAVA接口省事 :joy:

8个月前 评论
小狼 (楼主) 8个月前
$res = SmSignFormatRS::asn1_to_rs($sign, "hex");
$res = bin2hex(base64_decode($res));

签名处理后验证没有问题,得看你们那的java得到的签名对不对了

8个月前 评论

@deatil 你这个签名是composer require lpilp/guomi这个包生成的吗,这个确实能验证通过,另外方便看下你的$sign咋生成的吗,和我的方法不一样吗。我生成的验证不通过那

f7bc8e4e12eeb381688c579817939e9706cd6c3768a0b8e1e4e014db2efcc67cab9fc94879f68fadc23b3b9a84522d3bef9faf1deb57f601f080c33c31f8cd37

我的代码

use Rtgm\sm\RtSm2;
use Rtgm\util\SmSignFormatRS;

$sm2 = new RtSm2('hex', false);
$document = '12345678';
echo "原始: $document"."<hr>";
$publicKey = '7FF1D10F4DDF67F9147B820900B4EDD915B65F8614D88DB02CFDDCEEEDE7A58B17118400DD172D2FCE8BC16E601455E2BFEA4E0553964FD1293B8CC18B66335D';
// 私钥
$privateKey = '24EE8C7931D7031E90A032ADB16CB31DD33F74E99A595823E7571C66D8287816';
$userId = '31323334353637383132333435363738';
$m2SignData = $sm2 ->doSign($document, $privateKey, $userId);
$res = SmSignFormatRS::asn1_to_rs($m2SignData, "hex");
$res = bin2hex(base64_decode($res));
echo '原始签名';
var_dump($m2SignData);
echo '<hr>';
echo ("处理后: ");
var_dump($res);

原始签名string(140) "304402205fa066ce9671d5fd5c309896f72f8a5b8908e0c06da77c1440fcb770373c13500220658ba0ce573231cb3e9862f5b2d1956b4fe9689e58d1994585eb893e37562d00"
处理后: string(128) "5fa066ce9671d5fd5c309896f72f8a5b8908e0c06da77c1440fcb770373c1350658ba0ce573231cb3e9862f5b2d1956b4fe9689e58d1994585eb893e37562d00"
8个月前 评论
deatil 8个月前
deatil 8个月前
小狼 (作者) (楼主) 8个月前
Potato1 5个月前
deatil 5个月前
deatil 5个月前
Potato1 5个月前
deatil 5个月前
Potato1 5个月前
deatil 5个月前
Potato1 5个月前
deatil 5个月前
Potato1 5个月前
Potato1 5个月前
deatil 5个月前
Potato1 5个月前

直接调用jar包是最快的

5个月前 评论

file

大家使用过证书密钥进行sm2怎么加密吗?

5个月前 评论

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!