Как сохранить личный ключ RSAParameter в C # /. Net - PullRequest
0 голосов
/ 04 декабря 2018

Начиная с .Net 4.7.2 (.Net Standard 2.0) можно создавать самозаверяющие сертификаты и запросы на подпись сертификатов только с помощью C # /. Net, см. Документацию MS .

Хотя создать самозаверяющий сертификат, который будет утверждать HasPrivateKey (просто позвоните CreateSelfSigned(notBefore, notAfter)), довольно сложно, но мне сложно понять, как вообще получить закрытый ключ, например, еслиЯ хочу создать сертификат, подписанный центром сертификации, а затем сохранить сертификат в виде файла PFX или сохранить личный ключ в файле .PEM или сохранить его в хранилище сертификатов MS вместе с закрытым ключом,или когда я просто хочу иметь в памяти и также утверждать HasPrivateKey.

То, что у меня есть, это экземпляр «RSAParameters», который обладает соответствующей частной информацией, но я не смог понять, как(легко) использовать это для рассматриваемой цели (создать файл PFX или файл PEM или запись в хранилище сертификатов MS), не просматривая все версииvant RFCs и написать программу для этого самостоятельно.(Этот экземпляр RSAParameter содержит D, Exponent и Modulus, поэтому я мог бы попытаться исправить это вместе (с помощью этот ответ , надеюсь), но я надеялся на C #метод, который будет выполнять эти задачи для меня (который я пока не смог найти).

Конечно, идея заключается в том, чтобы сделать это только с помощью .Net.

Любой намек на то, как этого добиться, приветствуется.

Ответы [ 2 ]

0 голосов
/ 04 декабря 2018

Если у вас есть только Modulus, Exponent и D, сначала вы должны восстановить параметры CRT (P, Q, DP, DQ, InverseQ).

Как и другие ваши вопросы, в основном вам не хватает методов расширения cert.CopyWithPrivateKey(key) и rsa.ImportParameters(RSAParameters):

, если я хочу создать сертификат, подписанный ЦС, а затем хочусохранить сертификат в виде файла PFX

using (RSA rsa = RSA.Create())
{
    rsa.ImportParameters(rsaParameters);

    using (X509Certificate2 caSigned = GetCASignedCert(rsa))
    using (X509Certificate2 withKey = caSigned.CopyWithPrivateKey(rsa))
    {
        File.WriteAllBytes("some.pfx", withKey.Export(X509ContentType.Pkcs12, "and a password"));
    }
}

или сохранить личный ключ в файле .PEM

Этот файл доступен в .NETЕжедневные сборки Core 3.0:

RSAParameters rsaParameters = default(RSAParameters);

using (StreamWriter writer = new StreamWriter("rsa.key"))
using (RSA rsa = RSA.Create())
{
    rsa.ImportParameters(rsaParameters);

    writer.WriteLine("-----BEGIN RSA PRIVATE KEY-----");

    writer.WriteLine(
        Convert.ToBase64String(
            rsa.ExportRSAPrivateKey(),
            Base64FormattingOptions.InsertLineBreaks));

    writer.WriteLine("-----END RSA PRIVATE KEY-----");
}

PKCS # 8 и зашифрованный PKCS # 8 также доступны.

В существующих версиях это требует использования RSAParameters и кодера ITU-T X.690 DER.

или хотите сохранить его в хранилище сертификатов MS вместе с закрытым ключом

using (RSA rsa = RSA.Create())
{
    rsa.ImportParameters(rsaParameters);

    using (X509Certificate2 caSigned = GetCASignedCert(rsa))
    using (X509Certificate2 withKey = caSigned.CopyWithPrivateKey(rsa))
    using (X509Store store = new X509Store(StoreName.My, StoreLocation.CurrentUser))
    {
        X509Certificate2 persisted = new X509Certificate2(
            withKey.Export(X509ContentType.Pkcs12, ""),
            "",
            X509KeyStorageFlags.PersistKeySet);

        using (persisted)
        {
            store.Open(OpenFlags.ReadWrite);
            store.Add(persisted);
        }
    }
}

или когда я просто хочу иметь в памяти итакже утверждаем HasPrivateKey.

using (RSA rsa = RSA.Create())
{
    rsa.ImportParameters(rsaParameters);

    using (X509Certificate2 caSigned = GetCASignedCert(rsa))
    {
        // Yes, this value can outlive both usings
        return caSigned.CopyWithPrivateKey(rsa);
    }
}
0 голосов
/ 04 декабря 2018

Если вы используете модуль аппаратного обеспечения безопасности сертификата (HSM), например, например, USB-ключ, получить «закрытый ключ» невозможно, поскольку HSM предоставляет только интерфейс для использования закрытого ключа.Это для безопасности, так как, когда закрытый ключ находится в файле или памяти, он может быть получен третьей стороной.

Кроме того, .NET исторически не представлял достаточно гибкий интерфейс, хотя и улучшается.Многие поставщики программного обеспечения используют более полный и ухоженный API Bouncy Castle (http://www.bouncycastle.org/csharp/)), и вы найдете много документации по всему Интернету. Обычно, если .NET не может это сделать, то Bouncy Castle будетПо иронии судьбы HSM требует криптографического доступа .NET к своим функциям с закрытым ключом в Windows, но обычно вы как-то инкапсулируете это.имея пример кода, который вы хотите заставить работать.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...