lpilp / phpsm2sm3sm4

php版本,支持国密SM2的签名算法,非对称加解密,SM3的hash, SM4的对称加解密
320 stars 74 forks source link

对接招行时,对招行的数据返回进行验签时,偶现错误 ASN.1 Parser Exception at offset XX: Integer not minimally encoded #69

Closed zhiYu2017 closed 9 months ago

zhiYu2017 commented 9 months ago

在对接招行时发现一个情况,对招行的返回结果进行解签时会偶尔会报错 ASN.1 Parser Exception at offset XX: Integer not minimally encoded; 追踪代码路径发现对招行返回的sign 进行序列化处理时出现的异常 $sign ="MEQCIE8xlWrrSZhfvXx6LcqPEOj8n7c9N8UBkc0Wyu4He/lxAiAAY0rLn56jZNNdmNlakYaRbIz1ZgwfLfwlGKbCgpBbOA=="; $sigData = base64_decode($sign]); $sigSerializer = new DerSignatureSerializer(); $sig = $sigSerializer->parse($sigData); 错误路径如下 image

具体错误原因还不清楚,麻烦大佬帮忙调试一下

lpilp commented 9 months ago

招行那边的BUG, 他的代码里做asn1的时候,没有遵守规范,你这个解开为

Array
        (
            [0] => 4f31956aeb49985fbd7c7a2dca8f10e8fc9fb73d37c50191cd16caee077bf971  // r  64字符
            [1] => 00634acb9f9ea364d35d98d95a9186916c8cf5660c1f2dfc2518a6c282905b38 // s  64字符
        )

正常情况下r,s都是 64字符,有小概率是小于64, 如这个例子,s 部分做了00补齐, 然后用asn1序列化,它的序列化程序是自己实现的,非标准的,标准的是如果是大于7F开头的前面才要补00, 这个为了补齐加了00,而后面只有63,这个就报错了,同理大于7F的时候,可能对方也不补00,用标准化的asn1就会报错。我记得他们家新的sdk 没有这个问题,就没有专门在 readme 里提 解决方案: 1 将这个warning 注释掉,好像不影响。 2 在util目录下有个 FormatSign.php类,只要 FormatSign::run() 下,然后再解签就没问题了

zhiYu2017 commented 9 months ago

我采用了方案2,解决了,感谢