无法从.net x509certificate2对象获取私钥到bouncycastle AsymmetricCipherKeyPair

时间:2017-11-08 06:29:58

标签: c# cryptography bouncycastle x509certificate2 pkcs#7

我试图从此代码获取 pkcs-7签名 X509Certificate2 对象的密钥对。

RSACryptoServiceProvider key = (RSACryptoServiceProvider)Cert.PrivateKey;
RSAParameters rsaparam = key.ExportParameters(true);
AsymmetricCipherKeyPair keypair = DotNetUtilities.GetRsaKeyPair(rsaparam);

如果 X509Certificate2对象是使用.pfx 这样的文件创建的,那么这很好用

X509Certificate2 cert = new X509Certificate2(".pfx file path", "password");

它工作正常。  但是当证书从证书商店列出时,就像这样

 X509Certificate2 cert;
 X509Store UserCertificateStore = new X509Store("My");
 UserCertificateStore.Open(OpenFlags.ReadOnly);
 var certificates = UserCertificateStore.Certificates;
 foreach (var certificate in certificates)
 {
    if (certificate.Thumbprint==thumbprint)
    {
       cert=certificate;
       break;
    }
 }

它会在邮件中引发异常 - 密钥无法在指定状态下使用。

在@ Crypt32回答尝试使用RSA方法签名哈希

之后
RSACryptoServiceProvider csp = (RSACryptoServiceProvider)cert.PrivateKey;

using (SHA256Managed sHA256 = new SHA256Managed())
{
    byte[] hash = sHA256.ComputeHash(data);
    return csp.SignHash(hash, CryptoConfig.MapNameToOID("SHA256"));
}

但签名不是PKCS#7格式

2 个答案:

答案 0 :(得分:0)

这是因为BouncyCastle尝试从.NET对象获取原始密钥材料(字面意思是导出),而实际密钥未标记为可导出。在Windows系统中,密钥存储在加密服务提供程序中,用于控制所有密钥操作。当您需要执行特定的加密操作时,您要求CSP完成一项工作,而无需向您公开密钥材料。如果密钥是在CSP中导出/生成为可导出的,则可以要求CSP导出密钥材料。如果未设置此标志,CSP将不会为您提供密钥。

我不知道BouncyCastle是如何工作的,但如果它需要原始密钥材料,那么您的证书中需要可导出的私钥。

答案 1 :(得分:0)

要回答基本问题,“如何使用RSA + SHA-2-256签署PKCS#7 SignedData消息?”

https://github.com/Microsoft/dotnet/blob/master/releases/net471/dotnet471-changes.md#bcl说SHA-2-256不仅适用于4.7.1,而且现在是默认值:

  

更新了SignedXML和SignedCMS,将SHA256用作SHA1的默认值。通过启用上下文切换,SHA1仍可被选中作为默认值使用。 [397307,System.Security.dll,Bug]

在较旧的框架上,可以通过:

ContentInfo content = new ContentInfo(data);
SignedCms cms = new SignedCms(content);
CmsSigner signer = new CmsSigner(cert);
signer.DigestAlgorithm = new Oid("2.16.840.1.101.3.4.2.1");
cms.ComputeSignature(signer);
return cms.Encode();

其中“2.16.840.1.101.3.4.2.1”是SHA-2-256的OID-ese。