通过BouncyCastle包进行Java签名C#验签时要注意asn1编码转换

这篇博客探讨了在Java使用BouncyCastle库进行SM2签名后,如何处理签名结果以适应C#应用中的asn1编码验证。Java端生成的签名是直接拼接的r||s字节数组,而C#的BouncyCastle.Crypto库需要asn1编码的签名。通过提供两个方法,实现了asn1编码和非asn1编码签名字符串之间的转换,从而实现跨平台的验签功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在Java中采用BouncyCastle的Jar(bcprov-jdk15on-1.58.jar)对授权数据进行签名。因为项目的历史原因,没用采用更高版本jar包。签名后,把授权数据和签名发给C#的应用进行验签。由于Java端的签名结果是由64字节组成的hex字符串,是直接拼接r||s的字节数组,没用经过asn1编码的。在C#应用端通过NuGet引入BouncyCastle.Crypto的版本为1.9.0.0。该库中的对象SM2Signer自带的验签方法VerifySignature的参数是需要带asn1编码的签名hex字符串。因此,需要把从Java中传来的签名字符串先进行asn1编码后,在传给验签函数VerifySignature进行验签。asn1编码互转的方法如下:

/**
         * BC的SM3withSM2验签需要的rs是asn1格式的,这个方法将直接拼接r||s的字节数组转化成asn1格式
         * @param sign in plain byte array
         * @return rs result  asn1格式
         */
        public static byte[] RsByteArrayToAsn1(byte[] sign)
        {
            if (sign.Length != 32 * 2) throw new ArgumentException("err rs. ");
            BigInteger r = new BigInteger(1, Arrays.CopyOfRange(sign, 0, 32));
            BigInteger s = new BigInteger(1, Arrays.CopyOfRange(sign, 32, 32 * 2));
            Asn1EncodableVector v = new Asn1EncodableVector();
            v.Add(new DerInteger(r));
            v.Add(new DerInteger(s));
            try
            {
                return new DerSequence(v).GetEncoded("DER");
            }
            catch (IOException e)
            {
                log.Error("RsPlainByteArrayToAsn1 error: " + e.Message, e);
                return null;
            }
        }

/**
        * BC的SM3withSM2签名得到的结果的rs是asn1格式的,这个方法转化成直接拼接r||s
        * @param rsDer rs  asn1 格式
        * @return sign result in plain byte array
        */
        public static byte[] RsAsn1ToByteArray(byte[] rsDer)
        {
            Asn1Sequence seq = Asn1Sequence.GetInstance(rsDer);
            byte[] r = BigIntToFixexLengthBytes(DerInteger.GetInstance(seq[0]).Value);
            byte[] s = BigIntToFixexLengthBytes(DerInteger.GetInstance(seq[1]).Value);
            byte[] result = new byte[32 * 2];
            Buffer.BlockCopy(r, 0, result, 0, r.Length);
            Buffer.BlockCopy(s, 0, result, 32, s.Length);
            return result;
        }

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值