首页 > 解决方案 > 在 C# 中以编程方式将 .crt + .key 文件转换为 X509Certificate2

问题描述

我在 Linux 机器上有一个 .crt 证书和一个 .key 私钥文件。私钥采用加密的 PKCS#8 格式(BEGIN ENCRYPTED PRIVATE KEY...)。我想将这些导入到 X509Certificate2 对象中以供进一步使用。由于我们使用的是 Linux,因此我们使用的是 .NET Core 2.2(我们还不能迁移到 3.0)。

我探索了一些可能的解决方案,详细如下:

  1. 用于openssl将文件转换为 .pfx 并使用 X509Certificate2 导入
    • 我不想使用这个选项,因为我不想在 C# 中执行 shell 代码。我希望在 C# 中完全以编程方式实现该解决方案。
  2. 使用 C# BouncyCastle 库执行以下任一操作:
    • 将证书和密钥都转换为 .pfx(如上),或
    • 分别导入证书和私钥,并X509Certificate2.CopyWithPrivateKey()用于组合它们。
    • 但是,我找不到 C# 版本的 BouncyCastle 的 API,所以我不确定我可以使用哪些方法来执行此操作。
  3. 我在这里缺少的 C# 中的其他一些编程方法

本质上,最终目标是从 .crt 和 .key 文件中获取 X509Certificate2 对象。任何有关使用哪种方法的帮助/见解,甚至是指向有用的 BouncyCastle 文档的指针,都将不胜感激。谢谢!

标签: c#bouncycastlex509

解决方案


这在 .NET Core 3.0 中是可能的,尽管不像它可能的那么友好:

private static byte[] UnPem(string pem)
{
    // This is a shortcut that assumes valid PEM
    // -----BEGIN words-----\nbase64\n-----END words-----
    const string Dashes = "-----";
    int index0 = pem.IndexOf(Dashes);
    int index1 = pem.IndexOf('\n', index0 + Dashes.Length);
    int index2 = pem.IndexOf(Dashes, index1 + 1);

    return Convert.FromBase64String(pem.Substring(index1, index2 - index1));
}

...

string keyPem = File.ReadAllText("private.key");
byte[] keyDer = UnPem(keyPem);
X509Certificate2 certWithKey;

using (X509Certificate2 certOnly = new X509Certificate2("certificate.cer"))
using (RSA rsa = RSA.Create())
{
    // For "BEGIN PRIVATE KEY"
    rsa.ImportPkcs8PrivateKey(keyDer, out _);
    certWithKey = certOnly.CopyWithPrivateKey(rsa);
}

using (certWithKey)
{
    Console.WriteLine(certWithKey.HasPrivateKey);
}

RSA 私钥可以是三种不同的格式,您需要为每种格式调用正确的导入:

  • “开始私钥”:ImportPkcs8PrivateKey
  • “开始加密私钥”:ImportEncryptedPkcs8PrivateKey
  • “开始 RSA 私钥”:ImportRSAPrivateKey

推荐阅读