lpilp / phpsm2sm3sm4

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

PHP进行SM3withSM2签名,但是后端JAVA不认 #85

Closed fkcoward closed 4 days ago

fkcoward commented 2 weeks ago

老师,您好,我们现在正在接一个支付接口,这个支付平台上生成sm2的公钥私钥,我们拿私钥进行签名,用PHP的签名提交一直报验签失败,说明签名有问题。我用平台上给的JAVA demo里的代码把同样的字符串进行签名,就能成功。希望老师帮忙看看什么问题。 平台上生成的私钥: MIGTAgEAMxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxHTfHewOT7S8dmt164EXJx38f/igCgYIKoEcz1UBgi2hRANCAARMZOMzerr+4mAm0XYc4qItgA4OKhrPod8tVnPraTN/4lib/fDmM+IGp+7AwC7SnRBacwusweW42RYnzAxScoQs

平台上生成的公钥: MFkwEwYHKoZIzj0CAQYIKoEcz1UBgi0DQgAETGTjM3q6/uJgJtF2HOKiLYAODioaz6HfLVZz62kzf+JYm/3w5jPiBqfuwMAu0p0QWnMLrMHluNkWJ8wMUnKELA==

我用的咱们库进行签名的方法:

 protected function getSign($array)
    {
        ksort($array);
        $bufSignSrc = $this->toUrlParams($array);
        $ssm2 = new RtSm2("base64");
        $sign = $ssm2->doSign($bufSignSrc, bin2hex(base64_decode(AppConfig::sm2private)));
        return trim($sign);
    }

JAVA demo里用的

public static String sign(PrivateKey privateKey, String text) throws Exception
    {
        Signature signature = Signature.getInstance(ALGORITHM_SM3SM2_BCPROV, "BC");
        signature.initSign(privateKey);
        byte[] plainText = text.getBytes(StandardCharsets.UTF_8);
        signature.update(plainText);
        byte[] signatureValue = signature.sign();
        return Base64.toBase64String(signatureValue);
    }

其中,Signature 这个库就是package java.security; 里的,没看到有什么特殊处理。 是平台生成的私钥有问题吗?平台上还不能填自己生成的密钥对,只能用他们的。。。 实在弄不出来了,忘老师指点一下。

lpilp commented 2 weeks ago

这个是你使用的方法不对呢, 1 你的私钥是asn1过的pkcs8的私钥封装,需要解开出明文的私钥 2 公钥也是asn1封装的, 使用asn1 将公私钥解出来使用就行了,PS:可以半小时了解了 asn1, 然后就明白就怎么回事了