Closed maturethan closed 1 year ago
你先试下,不经过format直接使用,这个我以前试了下大概是几百分之一会出问题,经过处理是为了处理那个几百分1的问题,如果你试了好多组都有问题的话, 那可能现在招行改了代码的返回形式了, 还不行的话,你给一个签名,我试试,只给签名就行,
//招行单独处理-别人
$tmp = base64_decode($sm2_sign);
$a = \FG\ASN1\ASNObject::fromBinary($tmp)->getChildren();
$aa = $this->_formatHex($a[0]->getContent());
$bb = $this->_formatHex($a[1]->getContent());
$cc = $aa . $bb;
$final_sign = base64_encode(hex2bin($cc));
如果是这样可以的话就是招行改了签名的代码,正常的代码asn1(r,s ) , 这个 返回的 r + s ,如果别人的这种可以的话,你也这么处理,不过他这个处理也会有那个字节少的问题,aa, bb都应该是32字节的16进制,就是64的长度,如果长度不够前面得补0
你再看看看招行的文档,可能招行给的是两种形式,根据不同的参数返回不一样的签名,一种的asn1(r,s) ,就是我的代码里的, 还有一种的纯的 r +s 格式的
你先试下,不经过format直接使用,这个我以前试了下大概是几百分之一会出问题,经过处理是为了处理那个几百分1的问题,如果你试了好多组都有问题的话, 那可能现在招行改了代码的返回形式了, 还不行的话,你给一个签名,我试试,只给签名就行,
FAKcV6OrxEFS+vZjWW9SdqxZl0AR3FMg0tsxVEjLNhL3wkXafXnInG2Y+bBpQE22vpusJNY8uL2Pu2YcdF3VBg==
感谢大佬的回复,这是请求招行后招行返回的签名,大佬帮忙掌掌眼
就是我说的这是 r+s 格式的, 区别见 readme里常见问题,文档最后一行,解决方案是做一下 转换, 在src/util/SmSignFormatRS.php , 签名后将asn1转 r+s的格式,就是上面的那个 “//招行单独处理-别人” , 验证的时候,将别人的r+s 转成 asn1, 或者你你再看看招行给的文档,是否有相关的参数可以要求对方的返回值是 asn1方式,以前都是asn1方式的,应该改版后也要兼容以前的人的接入吧
就是我说的这是 r+s 格式的, 区别见 readme里常见问题,文档最后一行,解决方案是做一下 转换, 在src/util/SmSignFormatRS.php , 签名后将asn1转 r+s的格式,就是上面的那个 “//招行单独处理-别人” , 验证的时候,将别人的r+s 转成 asn1, 或者你你再看看招行给的文档,是否有相关的参数可以要求对方的返回值是 asn1方式,以前都是asn1方式的,应该改版后也要兼容以前的人的接入吧
大佬真的很抱歉,我太菜了 目前加签请求招行没问题了
//排序生json
$resData = $this->_dataSort($resData);
$data_str = json_encode($resData, JSON_UNESCAPED_UNICODE);
//sm2 sign
$priKey = bin2hex(base64_decode($this->_priKey));
$sm2 = new RtSm2("base64");
$sm2_sign = $sm2->doSign($data_str, $priKey, $iv);
//招行单独处理-github lpilp大佬
$final_sign = \Rtgm\util\SmSignFormatRS::asn1_to_rs($sm2_sign);
//上签
$httpDataStr = str_replace("__signature_sigdat__", $final_sign, $data_str);
但是收到招行的返回,验签还是false
$bak_sign = $array["signature"]["sigdat"];
$array["signature"]["sigdat"] = '__signature_sigdat__';
$bak_sign = \Rtgm\util\SmSignFormatRS::rs_to_asn1($bak_sign);
$array = $this->_dataSort($array);
$json = json_encode($array, JSON_UNESCAPED_UNICODE);
$publicKey = bin2hex(base64_decode($this->_pubKey));
$sm2 = new RtSm2("base64");
$b = $sm2->verifySign($json, $bak_sign, $publicKey, $userId);
大佬能不能再帮看下我验签是不是哪里还有不对
可能会有以下3个问题: 1 确认返回的签名是 asn1,还是r+s的,(10%) 2 $json 的值的问题(你算出来是否和他加签的时候一样),这个可以看给的sdk 或是文档 (30%) 3 pubKey的问题, 我这函数是支持的是 128(130的话是前面有04) hex 的公钥,如果一开始的公钥比较长的话,可能是asn1过的公钥,得解出公钥,使用 test/tasn1.php 可以解开下看下公钥,替换 (60%可能这个问题)
大佬我补充下,我用我自己request招行的字串直接验签,是能true的 但是招行 reponse 我的字串就验不过
可能会有以下3个问题: 1 确认返回的签名是 asn1,还是r+s的,(10%) 2 $json 的值的问题(你算出来是否和他加签的时候一样),这个可以看给的sdk 或是文档 (30%) 3 pubKey的问题, 我这函数是支持的是 128(130的话是前面有04) hex 的公钥,如果一开始的公钥比较长的话,可能是asn1过的公钥,得解出公钥,使用 test/tasn1.php 可以解开下看下公钥,替换 (60%可能这个问题)
好的真的非常感谢大佬,我研究看看
大佬我补充下,我用我自己request招行的字串直接验签,是能true的 但是招行 reponse 我的字串就验不过
那就是第2条的问题比较大,你看下他们的文档,可能那个signature这个字段不参与签名
可以了,感恩
编辑下方便后来者们捡个现成 招行云直联,直接用大佬的sdk 加密完 \Rtgm\util\SmSignFormatRS::asn1_to_rs 过一下丢给招行 招行的返回, \Rtgm\util\SmSignFormatRS::rs_to_asn1 过一下再验签就行
重点: 验签公钥要用招行公钥,不是用户公钥 !!!! 验签公钥要用招行公钥,不是用户公钥 !!!! 验签公钥要用招行公钥,不是用户公钥 !!!!
1、关于加密, 大佬在其它issue和样例代码提到需要先format_cmbc,但我实测不行,用别人的代码加密可以过
想了解是为什么呢,别人的代码我是learnku看的(地址/articles/68557)
2、关于解密 我收到招行response后
会卡死,无法解密
但是如果不用大佬的代码,直接
必定校验不过 运行大佬的demo是没问题的,没有思路,求大佬赐教,感谢感谢