我正在使用Wiktor Zychla(http://www.wiktorzychla.com/2012/12/how-to-create-x509certificate2.html(的这篇博客文章中的CertificateGenerator.GenerateCertificate
创建x509Certificate2
充气城堡加密库用于生成证书文件。我需要使用更强的签名算法,所以我使用的是SHA256withRSA
而不是SHA1withRSA
(示例中的一个(。
证书已成功生成并导出到.pfx
文件。稍后使用该证书时,我收到错误Invalid algorithm specified
。
certutil -dump mycert.pfx
运行时,我看到设置了不正确的加密服务提供程序(CSP(:Microsoft基本加密提供程序v1.0
。
---------------- 结束嵌套级别 1 ----------------
提供程序 = Microsoft 基本加密提供程序 v1.0
。
如何告诉充气城堡 API 使用不同的 CSP?
Microsoft增强型RSA和AES加密提供程序,实际上可以处理SHA256withRSA
。
关于充气城堡和C#
的资源很少,所以任何指向一些文档或相关示例的链接将不胜感激。
CryptoAPI CSP和算法列表,它们支持:
https://msdn.microsoft.com/en-us/library/windows/desktop/bb931357(v=vs.85(.aspx
最简单的方法是在导入生成的 pfx 时指定 CSP。您可以使用此命令
certutil -importPFX -csp "Microsoft Enhanced RSA and AES Cryptographic Provider" -v c:yourpfx.pfx AT_KEYEXCHANGE,NoExport,NoProtect
这将
- 导入到本地计算机\我的
- 将 CSP 设置为Microsoft增强型 RSA 和 AES 加密提供程序
- 将私钥用法设置为"交换"
- 将私钥设置为不可导出
- 设置没有额外(密码(保护的私钥
CSP是PKCS#12(PFX(中特定于窗口的字段,除了Windows之外,没有人设置它。如果从文件new X509Certificate2(filename)
使用 PFX,则必须更改私钥。将PrivateKey
属性转换为RSACryptoServiceProvider
并修改CspParameters
(我现在没有代码段(。然后将修改后的RSACryptoServiceProvider
设置回PrivateKey
属性。
-------编辑
下面是在从文件中读取的 PFX 上更改 CSP 的示例代码
// need to set exportable flag to be able to ... export private key
X509Certificate2 cert = new X509Certificate2(@"d:test.pfx", "a", X509KeyStorageFlags.Exportable);
var privKey = cert.PrivateKey as RSACryptoServiceProvider;
// will be needed later
var exported = privKey.ToXmlString(true);
// change CSP
var cspParams = new CspParameters()
{
ProviderType = 24,
ProviderName = "Microsoft Enhanced RSA and AES Cryptographic Provider"
};
// create new PrivateKey from CspParameters and exported privkey
var newPrivKey = new RSACryptoServiceProvider(cspParams);
newPrivKey.FromXmlString(exported);
// Assign edited private key back
cert.PrivateKey = newPrivKey;
// export as PKCS#12/PFX
var bytes = cert.Export(X509ContentType.Pfx, "a");
您可以在使用 BouncyCastle 导出 pfx 证书时进行设置。
它的文档记录非常少,但是在创建 pfx 时可以将 CSP 设置为包属性。要在BouncyCastle中执行此操作,您需要知道CSP名称字段的对象标识符,您可以将其设置为Pkcs12Store上的属性(对于Microsoft CSP,它是"1.3.6.1.4.1.311.17.1"(:
//Build your pem certificate as normal first
...
var certificate = certificateGenerator.Generate(new Asn1SignatureFactory(SignatureAlgorithm, issuerPrivateKey, random));
//cert and key hashing algorithms can be set on the builder if required
var pkcs12Store = new Pkcs12StoreBuilder().Build();
var certificateEntry = new X509CertificateEntry(certificate);
var microsoftCspNameObjectIdentifier = new DerObjectIdentifier("1.3.6.1.4.1.311.17.1");
pkcs12Store.SetKeyEntry(certificate.SubjectDN + "_key", new AsymmetricKeyEntry(subjectPrivateKey, new Dictionary<DerObjectIdentifier, Asn1Encodable> { { microsoftCspNameObjectIdentifier, new DerBmpString("Microsoft Enhanced RSA and AES Cryptographic Provider") } }), new[] { certificateEntry });
//Save your pkcs12 to a stream (file stream to save to file/memory stream if you want bytes etc)
pkcs12Store.Save(...);