如何使C#中的BouncyCastle签名字符串与Java提供的字符串完全一致?

时间:2018-09-26 14:08:06

标签: c# rsa bouncycastle sha256 x509certificate2

我有一个.pfx证书,该证书应该用于数字签名字符串消息。有一个用Java编写的可行示例已经可以完成预期的工作,但是我们的环境是基于C#的...

Java解决方案使用Bouncy Castle库,它很像类CMSSignedDataGenerator的文档示例,这里是:

        final byte[] buf = stringData.getBytes("UTF-8");

        CMSTypedData typedData = new CMSProcessableByteArray(buf);
        CMSSignedDataGenerator gen = new CMSSignedDataGenerator();

        ContentSigner signer = new JcaContentSignerBuilder(signatureAlgorithm).
                setProvider(ksProviderName).build(privateKey);

        JcaSignerInfoGeneratorBuilder builder = new JcaSignerInfoGeneratorBuilder(jcaDigestCalculatorProviderBuilder);
        gen.addSignerInfoGenerator(builder.build(signer, cert));
        CMSSignedData signed = gen.generate(typedData, false);
        byte[] der = signed.getEncoded();

        return Base64.getEncoder().encodeToString(der);

C#有Bouncy Castle实现,我们尝试使用它,但与Java不同,我们找不到与先前代码段对应的某些类(例如,我们找不到ContentSigner或JcaContentSignerBuilder )。

        X509Certificate2 x509c2 = Cert.Instance.Certificate;

        byte[] buf = Encoding.UTF8.GetBytes(stringData);

        CmsProcessableByteArray typedData = new CmsProcessableByteArray(buf);
        CmsSignedDataGenerator gen = new CmsSignedDataGenerator();

        RSAParameters rsaParameters = ((RSACryptoServiceProvider)x509c2.PrivateKey).ExportParameters(true);

        AsymmetricKeyParameter keyParameters = new RsaKeyParameters(
            true,
            new BigInteger(1, rsaParameters.Modulus),
            new BigInteger(1, rsaParameters.Exponent)
            );

        Org.BouncyCastle.X509.X509Certificate bcCert = (new Org.BouncyCastle.X509.X509CertificateParser()).ReadCertificate(x509c2.RawData);
        Asn1SignatureFactory signatureFactory = new Asn1SignatureFactory(x509c2.SignatureAlgorithm.Value, keyParameters);

        SignerInfoGeneratorBuilder signerInfoGeneratorBuilder = new SignerInfoGeneratorBuilder();

        gen.AddSignerInfoGenerator(signerInfoGeneratorBuilder.Build(signatureFactory, bcCert));

        CmsSignedData signed = gen.Generate(typedData, false);

        byte[] signedBytes = signed.GetEncoded();

        return Convert.ToBase64String(signedBytes);

返回值(base64编码的签名)与Java代码中的一个不匹配。来自Java的签名返回的字符串长度为820个字符,而从此C#代码中,我们得到756个字符(“我们是如此接近”-我的同事说:-))

是否有帮助获得匹配结果?

0 个答案:

没有答案