在 C# 中以编程方式将证书和私钥转换为 .PFX

Posted

技术标签:

【中文标题】在 C# 中以编程方式将证书和私钥转换为 .PFX【英文标题】:Convert Certificate and Private Key to .PFX programmatically in C# 【发布时间】:2016-02-15 17:23:03 【问题描述】:

我有一个成功的 LetsEncrypt 证书请求的 .cer 文件输出。

我有用于为 LetsEncrypt 创建证书签名请求 (CSR) 的原始私钥。

现在我们需要使用 .NET 以编程方式将这两个文件组合成一个用于 IIS 的 PFX 包

由于我们试图以编程方式执行此操作,因此 pvk2pfx 不实用,我们希望尽可能避免使用 openssl。

为了演示,我们尝试复制此功能,但使用 CS .NET 而不是 pvk2pfx: pvk2pfx.exe -pvk Server.pvk -spc Server.cer -pfx Server.pfx

我进行了详尽的研究,以下是我看到的可能性:

一种方法似乎是使用 X509Certificate2 之类的:

// Import the certificate
X509Certificate2 cert = new X509Certificate2("c:\\cert.cer");

// Import the private key
X509Certificate2 cert = new X509Certificate2("c:\\key.pvk");

// Or import the private key - Alternative method
X509DecryptString(token, @"c:\CA.pvk", "mypassword");

// Export the PFX file
certificate.Export(X509ContentType.Pfx, "YourPassword");
File.WriteAllBytes(@"C:\YourCert.pfx", certificateData);

这里有一些其他的方法,但它们似乎都省略了关于私钥的部分,或者它们需要 pvk2pfx.exe

从 cert 文件转换为 pfx 文件 https://***.com/a/4797392/3693688

如何以编程方式创建 X509Certificate2? http://www.wiktorzychla.com/2012/12/how-to-create-x509certificate2.html

选择、创建和查找 X509 证书: http://www.wou.edu/~rvitolo06/WATK/Demos/HPCImageRendering/code/ImageRendering/AppConfigure/CertHelper.cs

无法将生成的带有私钥的证书导出到字节数组 Cannot export generated certificate with a private key to byte array in .NET 4.0/4.5

如何以编程方式将带有证书链的 pfx 导入证书存储区。 https://***.com/a/9152838/3693688

在 C# 中以编程方式导入 .cer 和 .pvk 证书文件以用于netsh http add sslcert https://gist.github.com/BrandonLWhite/235fa12247f6dc827051

将cer转换为pfx cert的方法 https://gist.github.com/domgreen/988684


编辑 1

CryptoGuy 建议我们需要这个链接: https://gist.github.com/BrandonLWhite/235fa12247f6dc827051

这是否意味着这样的事情会很好?

CSP 部件是否必要?

using System.Security.Cryptography.X509Certificates;
using System.Security.Cryptography;

    var PublicKey = AssemblyUtility.GetEmbeddedFileAsByteArray("Cert.cer");
    var PrivateKey = AssemblyUtility.GetEmbeddedFileAsByteArray("PrivateKey.pvk");
    var certificate = new X509Certificate2(PublicKey, string.Empty, 
        X509KeyStorageFlags.MachineKeySet | X509KeyStorageFlags.PersistKeySet | X509KeyStorageFlags.Exportable);
    var cspParams = new CspParameters
    
        ProviderType = 1,
        Flags = CspProviderFlags.UseMachineKeyStore,
        KeyContainerName = Guid.NewGuid().ToString().ToUpperInvariant()
    ;
    var rsa = new RSACryptoServiceProvider(cspParams);

    rsa.ImportCspBlob(ExtractPrivateKeyBlobFromPvk(PrivateKey));
    rsa.PersistKeyInCsp = true;
    certificate.PrivateKey = rsa;

    certificate.Export(X509ContentType.Pfx, "YourPassword");
    File.WriteAllBytes(@"C:\YourCert.pfx", certificateData);

【问题讨论】:

您的一个链接 (gist.github.com/BrandonLWhite/235fa12247f6dc827051) 看起来是您的正确选择。 是的,CSP 部分是强制性的,因为它是在 Windows 中使用非对称加密的唯一支持方式。简而言之,您必须将私钥文件(PKCS#1、PKCS8 或其他)加载到 CSP 并将其与 X509Certificate2 对象相关联。 有趣,谢谢!看起来这可能是我们之前所缺少的。 certificate.Export(X509ContentType.Pfx...) 部分看起来正确吗?我已经从另一个来源复制了它并删除了 netsh 和 sCertHash 部分,因为我认为如果我们只是保存到 pfx 文件中我们不需要这些部分? netsh 部分是另一回事(你不需要这个)。您只需要获取代码中使用的ExtractPrivateKeyBlobFromPvk 方法(我不知道从哪里获取)。我怀疑他的代码只是将 PKCS#1/PKCS#8 私钥转换为 CryptoAPI 私钥 blob:msdn.microsoft.com/en-us/library/windows/desktop/… 可能是这样的? sysadmins.lv/blog-en/… 【参考方案1】:

CryptoGuy 的回答非常有帮助,并为我们指明了正确的方向。

我们仍在努力导入二进制 DER 文件,但这段代码解决了这个问题:

var oc = OpenSSL.X509.X509Certificate.FromDER(bio); 

这些页面很有用:

https://github.com/openssl-net/openssl-net/blob/master/ManagedOpenSsl/X509/X509Certificate.cs

https://msdn.microsoft.com/en-us/library/system.security.cryptography.x509certificates.x509certificate2.rawdata

感谢大家的帮助:)

【讨论】:

以上是关于在 C# 中以编程方式将证书和私钥转换为 .PFX的主要内容,如果未能解决你的问题,请参考以下文章

C#创建数字证书并导出为pfx,并使用pfx进行非对称加解密

如何把SSL公钥和私钥转化为PFX格式

pfx文件是不是包含根证书

sh [OpenSSL pfx转换]将.pfx证书转换为SSL证书和未加密的私钥#openssl #pfx #certificate #ssl #private #key #encr

使用 OpenSSL 以编程方式将 .PEM 证书转换为 .PFX

了解将 .pem 文件转换为 .pfx 的 OpenSSL 步骤 [关闭]