lpilp / phpsm2sm3sm4

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

对接国家医保平台的sm2withsm3的时候发现,这个签名的结果和java的签名不一致 #73

Closed zh7314 closed 6 months ago

zh7314 commented 6 months ago

目前明确的是sm4的结果的是一直的,但是sm2withsm3签名结果不一致

php的代码:

$pk = bin2hex(base64_decode($privateKey));

$sm2 = new RtSm2();
$sign = $sm2->doSign($str, $pk);

//pp("签名结果:" . base64_encode(hex2bin($sign)));

$base['signData'] = base64_encode(hex2bin($sign));

java代码经过测试生成的是可以请求成功的 参考的代码: https://blog.csdn.net/Qcg0223/article/details/135720914

链接:https://pan.baidu.com/s/1pDsGi8QcdZJQjDhhZsoNow 提取码:mt5t

猜测是签名时候的

public String sign(String plainText, String prvKey) throws NoSuchAlgorithmException, InvalidKeySpecException, InvalidKeyException, SignatureException, IOException {
        Signature signature = Signature.getInstance(GMObjectIdentifiers.sm2sign_with_sm3.toString(), this.provider);
        BigInteger bigInteger = new BigInteger(prvKey, 16);
        BCECPrivateKey privateKey = (BCECPrivateKey) this.keyFactory.generatePrivate(new ECPrivateKeySpec(bigInteger, this.ecParameterSpec));
        signature.initSign(privateKey);
        signature.update(plainText.getBytes(StandardCharsets.UTF_8));

        byte[] signByte = signature.sign();

        String str = new String(signByte);
//        System.out.println("签名字符串,未base64:" + str);

        String signStr = Base64.getEncoder().encodeToString(signByte);

        signStr = (new BigInteger(this.decoder.decode(signStr))).toString(16);

        System.out.println("签名字符串:" + signStr);

        String derStr = SM2Util.SM2SignAsn1.parseSm2SignAsn1Object(signStr);
        System.out.println("签名字符串:" + derStr);

        byte[] hexStr = Hex.decode(derStr);
        String signData = this.encoder.encodeToString(hexStr);
        return signData;
    }

感觉是这个函数的问题,截断了部分签名造成,有啥解决吗?

zh7314 commented 6 months ago

https://learnku.com/articles/68557

参考这个弄出来了

lpilp commented 6 months ago

https://learnku.com/articles/68557

参考这个弄出来了

搞定了就好

zh7314 commented 6 months ago

谢谢你的项目,这要是纯自己去实现这些算法,要的老命了,医保官方文档说的很多都不详细,给的java demo还有问题,东拼西凑才搞出来

lpilp commented 6 months ago

嗯嗯 ,只是上头要求用,下边的人都不太熟悉,现在比前几年好些了,前几年连银行的对接都有 bug,

zh7314 commented 6 months ago

嗯嗯 ,只是上头要求用,下边的人都不太熟悉,现在比前几年好些了,前几年连银行的对接都有 bug,

老哥,留个二维码,请你喝杯咖啡

lpilp commented 6 months ago

嗯嗯 ,只是上头要求用,下边的人都不太熟悉,现在比前几年好些了,前几年连银行的对接都有 bug,

老哥,留个二维码,请你喝杯咖啡

共同学习进步,这也只是当年一个KPI项目,还有很多不足

zh7314 commented 6 months ago

嗯嗯 ,只是上头要求用,下边的人都不太熟悉,现在比前几年好些了,前几年连银行的对接都有 bug,

老哥,留个二维码,请你喝杯咖啡

共同学习进步,这也只是当年一个KPI项目,还有很多不足

现在使用国密的项目越来越多,未来使用的人也会越多,后续有时间我会提交一些对接国密的demo,请喝杯咖啡是应该的