使用私钥将 X509Certificate2 导出到字节数组
Posted
技术标签:
【中文标题】使用私钥将 X509Certificate2 导出到字节数组【英文标题】:Export X509Certificate2 to byte array with the Private key 【发布时间】:2012-04-06 08:12:12 【问题描述】:我的商店中有一个 X509Certificate2 证书,我想使用 私钥导出到一个字节数组。证书字节数组必须是这样,当我稍后从字节数组导入证书时,私钥将具有私钥。
我尝试了很多方法,但没有成功导出带有私钥的证书。
X509Store store = new X509Store(StoreLocation.CurrentUser);
store.Open(OpenFlags.ReadOnly);
X509Certificate2 cert = store.Certificates[1];
byte[] certBytes = cert.GetRawCertData(); // Obviously does not work!
是否可以成功将带有私钥的证书导出到字节数组中?
非常感谢您的帮助。
【问题讨论】:
【参考方案1】:X509Certificate2
类的Export
函数允许您导出
带有字节数组私钥的证书。
以下代码演示了使用私钥导出证书:
X509Store store = new X509Store(StoreLocation.CurrentUser);
store.Open(OpenFlags.ReadOnly);
X509Certificate2 cert = store.Certificates[1];
// Export the certificate including the private key.
byte[] certBytes = cert.Export(X509ContentType.Pkcs12);
要保护您导出的证书,请使用 Export
函数的以下重载:
byte[] certBytes = cert.Export(X509ContentType.Pkcs12, "SecurePassword");
开始编辑
要导入证书,请使用以下代码:
X509Certificate2 certToImport = new X509Certificate2(arr, "SecurePassword");
// To mark it as exportable use the following constructor:
X509Certificate2 certToImport = new X509Certificate2(arr, "SecurePassword", X509KeyStorageFlags.Exportable);
// certToImport.HasPrivateKey must be true here!!
X509Store store2 = new X509Store(StoreName.TrustedPublisher,
StoreLocation.CurrentUser);
store2.Open(OpenFlags.MaxAllowed);
store2.Add(certToImport);
store2.Close();
结束编辑
【讨论】:
感谢您的回答,但我仍然遇到问题,当我运行您的代码并再次导入时,我得到 HasPrivateKey = false。可能是什么问题? @ErikLarsson:我已经更新了我的答案。希望这可以帮助。 HasPrivateKey 属性在我的机器上为真。如果我打开 MMC 导出导入的证书,我也可以导出私钥。 对于找到此线程的任何人,请注意,如果您想再次导出它,则需要在导入时将其设置为Exportable
,请参阅下一个答案以及***.com/questions/9358129/…
这将为 .NET 4.6.2 控制台应用程序抛出 System.Security.Cryptography.CryptographicException: 'Key not valid for use in specified state.'
。
@EivindGussiåsLøkseth:你到底从哪里得到异常?【参考方案2】:
未获得私钥的一个原因可能是它在最初添加到 CAPI 时已被标记为“不可导出”。在那种情况下,我认为这不是真正的解决办法。
【讨论】:
不,那只意味着你需要更强的技术。如果可以使用,可以导出。 @Joshua 不,当证书被标记为“不可导出”时,它只能用于通过操作系统对您的输入进行签名/解密,操作系统会返回结果。因此私钥可以使用,但受保护,不能导出。 @fjch1997:有时将调试器附加到 lsass。 @Joshua 当您从证书存储中获取证书时,处理私钥的不是托管代码 @fjch1997:嗯。当您使用内核调试器时,无论如何您都更喜欢本机代码。以上是关于使用私钥将 X509Certificate2 导出到字节数组的主要内容,如果未能解决你的问题,请参考以下文章
将私钥与 .net 中的 X509Certificate2 类关联