我有一个.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个字符(“我们是如此接近”-我的同事说:-))
是否有帮助获得匹配结果?