使用私钥将 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 类关联

X509Certificate2类怎样导入一个公钥字符串

如何创建一个最小的虚拟 X509Certificate2?

使用X509Certificate2类操作证书文件

x509certificate2 中的空 PrivateKey

X509Certificate2类怎样导入一个公钥字符串