C# 虽然设置了PrivateKey,但密钥集不存在
我正在尝试使用C# 虽然设置了PrivateKey,但密钥集不存在,c#,cryptography,certificate,rsa,x509certificate,C#,Cryptography,Certificate,Rsa,X509certificate,我正在尝试使用CmsSigner和附加X509证书对邮件进行签名: public static byte[] Sign(X509Certificate2 certificate, string keyXml) { ContentInfo contentInfo = new ContentInfo(new Oid("1.2.840.113549.1.7.1"), Encoding.ASCII.GetBytes("hello")); RSAC
CmsSigner
和附加X509证书对邮件进行签名:
public static byte[] Sign(X509Certificate2 certificate, string keyXml)
{
ContentInfo contentInfo = new ContentInfo(new Oid("1.2.840.113549.1.7.1"), Encoding.ASCII.GetBytes("hello"));
RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
rsa.FromXmlString(keyXml);
using (certificate.GetRSAPrivateKey())
{
certificate.PrivateKey = rsa;
}
var signer = new CmsSigner(certificate);
signer.DigestAlgorithm = new Oid("2.16.840.1.101.3.4.2.1");
signer.SignedAttributes.Add(new Pkcs9SigningTime());
var signedCms = new SignedCms(contentInfo, false);
signedCms.ComputeSignature(signer);
var encodeByteBlock = signedCms.Encode();
return encodeByteBlock;
}
证书没有密钥(HasPrivateKey
为false
),因此我使用使用OpenSSL生成的正确密钥设置它:
openssl req -new -sha256 -x509 -days 7300 -out ca.crt -keyout ca.key.pem -nodes
我将ca.key.pem转换为XML
但是当调用ComputeSignature
时,会引发此异常:
System.Security.Cryptography.CryptographyException:'密钥集不存在
存在'
堆栈跟踪:
在
System.Security.Cryptography.Pkcs.PkcsUtils.CreateSignerEncodeInfo(CmsSigner
签名者,布尔静默,安全密码(安全句柄和hProv)位于
System.Security.Cryptography.Pkcs.SignedCms.Sign(CmsSigner signer,
布尔沉默)在
系统。安全。加密。Pkcs。签名CMS。计算签名(CmsSigner
签名者,布尔沉默)在
系统。安全。加密。Pkcs。签名CMS。计算签名(CmsSigner
签名者)在控制台测试472.程序签名(X509Certificate2
证书,字符串(XML)中的
D:\me\Projects\ConsoleTest472\ConsoleTest472\Program.cs:at的第56行
控制台测试472.Program.Main(字符串[]args)位于
D:\me\Projects\ConsoleTest472\ConsoleTest472\Program.cs:第63行
我使用的代码有什么问题?设置私钥时是否设置了密钥集?私钥必须是:
- 在执行代码的用户的
密钥存储中MY
- 在机器的
密钥存储中,授予用户权限MY
- 与证书一起存储在PFX/PKCS#12文件中,并作为X509Certificate2加载,密码保护它
var signedCms = new SignedCms(contentInfo, false);
using (X509Certificate2 certWithKey = certificate.CopyWithPrivateKey(rsa))
{
var signer = new CmsSigner(certWithKey);
signer.DigestAlgorithm = new Oid("2.16.840.1.101.3.4.2.1");
signer.SignedAttributes.Add(new Pkcs9SigningTime());
signedCms.ComputeSignature(signer);
}
var encodeByteBlock = signedCms.Encode();
return encodeByteBlock;
它完成将私钥绑定到证书副本的工作(而不是进行变异),并执行任何必要的操作(在这种情况下,它将最终用RSACng密钥替换RSACNcryptoServiceProvider密钥,因为平台只支持仅用于内存(临时)密钥的CNG).我知道我的代码没有意义,但当PrivateKey设置为
RSACryptServiceProvider
对象且HasPrivateKey为true
时,为什么它找不到密钥集?它可能意味着“这是一个仅存储的密钥,但我需要一个命名密钥”或“此密钥只有公钥信息,但我需要私钥”,或“嗯,这个密钥本应存储在一个文件中,但该文件丢失了”。在您的情况下,我想它说“我是一个名为NULL的持久化密钥”,然后加载返回为“我找不到一个没有名称的密钥…”。您不应该使用PrivateKey setter,应该避免使用它的getter。
var signedCms = new SignedCms(contentInfo, false);
using (X509Certificate2 certWithKey = certificate.CopyWithPrivateKey(rsa))
{
var signer = new CmsSigner(certWithKey);
signer.DigestAlgorithm = new Oid("2.16.840.1.101.3.4.2.1");
signer.SignedAttributes.Add(new Pkcs9SigningTime());
signedCms.ComputeSignature(signer);
}
var encodeByteBlock = signedCms.Encode();
return encodeByteBlock;