赞
踩
最近一个项目客户端是使用c++写的,后端是java写的,两端通信报文加解密和签名都使用的SM2算法,直到有一天,后台交易成功了,但是客户端验签失败了,导致第三方从客户端拿到的验签失败报文,认为交易失败。
因为交易一直正常,这是一个偶发性的失败交易,但是生产环境无小事,不错过任何一个错误,就开始处理,拿到的的签名数据如下,一条验签成功、一条验签失败的:
#验签成功的
304402201565F15B99499AB72650045445834DB5D71B31C39F5B9D5ABEFA81B1C03D6EF7022009AEA386A134130E3FA4B7A082424D0495E631C44F7790705D8F74118A0D4EB9
#验签失败的
3044021f03e73355393992dfe05739866e1528fe8d0477d05b2a3589fcb75301336377022100e7212753fafb33dce1e0c74af3017e1c50b1e665820feec64b64a5f8edec2ddd
根据R、S签名值进行分解,如下:
#验签成功的
30
44
0220
1565F15B99499AB72650045445834DB5D71B31C39F5B9D5ABEFA81B1C03D6EF7
0220
09AEA386A134130E3FA4B7A082424D0495E631C44F7790705D8F74118A0D4EB9
#验签失败的
30
44
021f
03e73355393992dfe05739866e1528fe8d0477d05b2a3589fcb75301336377
0221
00e7212753fafb33dce1e0c74af3017e1c50b1e665820feec64b64a5f8edec2ddd
从上面可以看出验签失败的签名中R部分长度只有1f字节,十进制31个字节,正常应该有32字节,所以导致在客户端验签失败,因为客户端是按照标准的32字节去处理的。
经查阅资料,是因为R部分的签名删除了前导00,删除的规则是基于签名部分第一个字节是不是1开头,如果是1开头需要添加00,否则可以删除前导00,所以我们给客户端的时候需要在业务层进行补00即可。
参考资料:
https://blog.csdn.net/softt/article/details/134941449
https://blog.csdn.net/baikeley74/article/details/129703735
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。