Экспорт закрытого ключа из объекта X509Certificate

#c# #certificate #base64 #private-key #x509certificate2

#c# #сертификат #base64 #закрытый ключ #x509certificate2

Вопрос:

Мы используем код C #, создаем X509Certificate2 с файлом .p12, в конструктор вставляем путь к сертификату, пароль сертификата. Мы также пометили его как экспортируемый, как показано ниже:

 X509Certificate2 x509Certificate2 = new X509Certificate2
("...\MyCerificate.p12", "P@ssw0rd", X509KeyStorageFlags.Exportable);
  

мы получаем закрытый ключ в формате асимметричного алгоритма следующим образом:

 x509Certificate2.PrivateKey
  

Теперь мы хотим получить закрытый ключ из сертификата в формате Base64, но мы понятия не имеем, как это сделать, и это так важно для нас.

Комментарии:

1. С чем вы пытаетесь использовать вывод Base64? Это строгая необходимость или предпочтение?

Ответ №1:

Важный вопрос: почему base64?

Если это для вашего собственного приложения, вы можете сохранить закрытый ключ в виде строки XML (намного проще :-).

 string xml = x509Certificate2.PrivateKey.ToXmlString (true);
  

Если вам нужен base64 (опять же, только для вашего приложения), вы можете экспортировать ключ (RSAParameters), затем объединить все byte[] и превратить объединенный вывод в строку base64.

Но если вы хотите взаимодействовать с другими приложениями, для которых требуется закрытый ключ base64, вам нужно знать формат (внутри строки base64). Например. во многих случаях закрытые ключи кодируются в PEM (это base64 со специальным верхним / нижним колонтитулом, см. Пример X509Certificate ).

Если это то, что вы ищете, вам нужно сначала закодировать закрытый ключ в структуре PKCS # 8, затем перейти в base64 и добавить верхний / нижний колонтитул. Вы можете найти полезный код для этого внутри Mono.Security.dll (Лицензионный код MIT.X11 из проекта Mono).

Комментарии:

1. Я отказался от другого приложения, которому требуется получить закрытый ключ base64. Я хочу разрешить пользователю вставлять X509Certificate2 и самостоятельно извлекать закрытый ключ в формате base 64 — знаете ли вы, если. Net framework предоставляет какой-либо способ сделать это?

2. НЕТ, если бы это было так (я действительно сомневаюсь в этом) или если бы я знал, я бы включил его в свой ответ. При этом ваша проблема остается, это не проблема base64 , это знание того, что внутри важно для взаимодействия с другим вашим приложением.

3. Ссылка PKCS # 8 кажется мертвой, я ожидал увидеть там статью, но я получаю только обзор проектов RSA Labs

Ответ №2:

Вы можете просто использовать свойство PrivateKey для X509Certificate2. Фактическая реализация возвращаемого закрытого ключа зависит от алгоритма, используемого в сертификате — обычно это RSA:

 rsaObj = (RSACryptoServiceProvider)myCertificate.PrivateKey; 
  

После этого вы сможете получить информацию о ключе RSA из его свойства ExportParameters.

Комментарии:

1. и когда мы знаем информацию о ключе (например, RSA-PKCS1-KeyEx), как мы можем преобразовать закрытый ключ в base64?

Ответ №3:

Вы можете сделать это с помощью библиотеки OpenSSL для .NET:

 using DidiSoft.OpenSsl;
...
X509Certificate2 x509Certificate2 = new X509Certificate2
("...\MyCerificate.p12", "P@ssw0rd", X509KeyStorageFlags.Exportable);

PrivateKey privKey = PrivateKey.Load(x509Certificate2.PrivateKey);
bool withNewLines = true;
string base64PrivateKey = privKey.ToBase64String(withNewLines);
  

Ответ №4:

Если ваша единственная проблема заключается в кодировании закрытого ключа Base64, вы можете просто сделать так:

 var privateKey = x509Certificate2.PrivateKey;
var encoding = new System.Text.ASCIIEncoding();
var base64String = Convert.ToBase64String(encoding.GetBytes(privateKey.ToString()));
  

Комментарии:

1. PrivateKey. toString() возвращает «System. Безопасность. Cryptography.RSACryptoServiceProvider»….., это не закрытый ключ…

2. @RRR правильно. Вы обнаружите, что X509Certificate2 . PublicKey.Key.toString() вернет то же значение, делая это таким образом. Это не может быть правильным 🙂