извлечь байты закрытого ключа в C # - PullRequest
3 голосов
/ 07 июня 2011

В настоящее время я могу извлечь закрытый ключ из файла PFX, используя OpenSSL, используя следующие команды:

openssl pkcs12 -in filename.pfx -nocerts -out privateKey.pem

openssl.exe rsa -in privateKey.pem -out private.pem

Файл private.pem начинается с ---BEGIN RSA PRIVATE KEY--- и заканчивается ---END RSA PRIVATE KEY---

Я хочу сделать то же самое в C #, используя библиотеки .NET или библиотеку Bouncy Castle.

Как мне это сделать?

Ответы [ 4 ]

5 голосов
/ 07 июня 2011

Вот что у меня сработало.Также должно работать на вас:

using System;
using System.IO;
using System.Security.Cryptography;
using System.Security.Cryptography.X509Certificates;
using System.Text;
using Org.BouncyCastle.Crypto;
using Org.BouncyCastle.OpenSsl;
using Org.BouncyCastle.Security;

namespace SO6258771
{
    class Program
    {
        static void Main()
        {
            // Load your certificate from file
            X509Certificate2 certificate = new X509Certificate2("filename.pfx", "password", X509KeyStorageFlags.Exportable | X509KeyStorageFlags.PersistKeySet);

            // Now you have your private key in binary form as you wanted
            // You can use rsa.ExportParameters() or rsa.ExportCspBlob() to get you bytes
            // depending on format you need them in
            RSACryptoServiceProvider rsa = (RSACryptoServiceProvider)certificate.PrivateKey;

            // Just for lulz, let's write out the PEM representation of the private key
            // using Bouncy Castle, so that we are 100% sure that the result is exaclty the same as:
            // openssl pkcs12 -in filename.pfx -nocerts -out privateKey.pem
            // openssl.exe rsa -in privateKey.pem -out private.pem

            // You should of course dispose of / close the streams properly. I'm skipping this part for brevity
            MemoryStream memoryStream = new MemoryStream();
            TextWriter streamWriter = new StreamWriter(memoryStream);
            PemWriter pemWriter = new PemWriter(streamWriter);

            AsymmetricCipherKeyPair keyPair = DotNetUtilities.GetRsaKeyPair(rsa);
            pemWriter.WriteObject(keyPair.Private);
            streamWriter.Flush();

            // Here is the output with ---BEGIN RSA PRIVATE KEY---
            // that should be exactly the same as in private.pem
            Console.Write(Encoding.ASCII.GetString(memoryStream.GetBuffer()));
        }
    }
}
5 голосов
/ 07 июня 2011

Я обнаружил, что PEMwriter работает только для .NET 2.0 в VS2005.Среда .NET 3.5 SDK подчеркивает pemWriter.WriteObject(keyPair.Private); как ошибку из-за проблемы приведения.Если вы попытаетесь привести его к PEMObjectGenerator и, наконец, скомпилировать и отладить код, InvalidCastException генерируется, когда отладчик попадает в эту строку кода.Я также сообщу об этом на форуме надувных замков.

0 голосов
/ 04 октября 2018

Похоже, что API B # Bouncy Castle изменился, и текущий ответ больше не работает. Я не смог найти ответы на вопросы о том, как использовать его сейчас, поэтому оставлю этот обновленный пример. Хитрость заключается в использовании MiscPemGenerator.

void ConvertPfxToPem(
    string pfxPath,
    string pfxPassword,
    string keyPath)
{
    using (Stream stream = File.Open(pfxPath, FileMode.Open))
    {
        Pkcs12Store pkcs = new Pkcs12Store(stream, pfxPassword.ToCharArray());

        foreach (string alias in pkcs.Aliases)
        {
            if (pkcs.IsKeyEntry(alias) && pkcs.GetKey(alias).Key.IsPrivate)
            {
                AsymmetricKeyParameter privateKey = pkcs.GetKey(alias).Key;

                using (Stream s = new FileStream(keyPath, FileMode.Create))
                using (TextWriter textWriter = new StreamWriter(s))
                {
                    var generator = new MiscPemGenerator(privateKey);

                    PemWriter pemWriter = new PemWriter(textWriter);
                    pemWriter.WriteObject(generator);
                    textWriter.Flush();
                }
            }
        }
    }
}
0 голосов
/ 07 июня 2011

Класс System.Security.Cryptography.X509.x509certificate2 имеет свойство PrivateKey

вы можете получить объект x509certificate2 из объекта X509Store

Если у вас есть права на закрытый ключ, он будет в объекте X509Certificate2 (поэтому этот объект на самом деле не представляет собой только сертификат)

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