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

在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
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值