Конвертируйте файлы .crt + .key в X509Certificate2 программно в C # - PullRequest
0 голосов
/ 30 сентября 2019

У меня есть сертификат .crt и файл закрытого ключа .key на компьютере с Linux. Закрытый ключ в зашифрованном формате PKCS # 8 (НАЧИНАЕТСЯ ЗАПИСАННЫЙ ЧАСТНЫЙ КЛЮЧ ...). Я хотел бы импортировать их в объект X509Certificate2 для дальнейшего использования. Поскольку мы работаем под Linux, мы используем .NET Core 2.2 (мы пока не можем перейти на 3.0).

Я рассмотрел несколько возможных решений, подробно описанных ниже:

  1. Используйте openssl, чтобы преобразовать файлы в формат .pfx и импортируйте их, используя X509Certificate2
    • Iя не хочу использовать эту опцию, так как я не хочу выполнять код оболочки из C #. Я хотел бы, чтобы решение было полностью программно достигнуто в C #.
  2. Используйте библиотеки C # BouncyCastle для выполнения:
    • преобразования как сертификата, так и ключа в.pfx (как указано выше) или
    • Импорт сертификата и закрытого ключа отдельно и использование X509Certificate2.CopyWithPrivateKey() для их объединения.
    • Однако я не могу найти API дляверсия BouncyCastle для C #, поэтому я не уверен, какие методы я мог бы использовать для этого.
  3. Какой-то другой программный метод в C #, который мне здесь не хватает

По сути, конечной целью является получение объекта X509Certificate2 из файлов .crt и .key. Любая помощь / понимание того, какой подход использовать, или даже указатель на полезную документацию BouncyCastle, будет высоко ценится. Спасибо!

1 Ответ

1 голос
/ 01 октября 2019

Это возможно, хотя и не так дружелюбно, как могло бы быть, в .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 могут быть в трех разных форматах, и вам нужно вызвать правильный импорт длякаждый из них:

  • «BEGIN PRIVATE KEY»: ImportPkcs8PrivateKey
  • «BEGIN ENCRYPTED PRIVATE KEY»: ImportEncryptedPkcs8PrivateKey
  • «BEGIN RSA PRIVATE KEY»:
...