У меня есть сгенерированная пара ключей RSA, сохраненная как PRIVATEKEYBLOB и PUBLICKEYBLOB, и мне нужно иметь возможность преобразовать эти ключи в форматы DER или PEM, чтобы я могла использовать ее в PHP или Python. Я понял, что мог бы использовать функцию CryptEncodeObject, чтобы конвертировать мой PRIVATEKEYBLOB в DER. Для этого мне нужно использовать флаг кодирования PKCS_RSA_PRIVATE_KEY. Но я не смог найти никакой подсказки о том, как конвертировать PUBLICKEYBLOB в DER.
Вот мой код для конвертации в PRIVATEKEYBLOB:
LPCSTR type = PKCS_RSA_PRIVATE_KEY;
DWORD encd = X509_ASN_ENCODING | PKCS_7_ASN_ENCODING;
DWORD dlen = 0;
if(!CryptEncodeObject(encd, type, key, null, &dlen))
{ LOG_ERROR(); return false; }
// Buffer allocation (der variable)
if(!CryptEncodeObject(encd, type, key, der, &dlen))
{ LOG_ERROR(); return false; }
Я проверяю свои ключи, сравнивая их с выводом инструмента openssl:
openssl rsa -pubin -inform MS\ PUBLICKEYBLOB -in pub.ms -outform DER -out pub.der
openssl rsa -inform MS\ PRIVATEKEYBLOB -in pri.ms -outform DER -out pri.der
ДОБАВЛЕНО: я пробовал RSA_CSP_PUBLICKEYBLOB с X509_ASN_ENCODING, но результат отличается от вывода инструмента openssl, и при импорте ключа происходит сбой. Экспортированный DER openssl на 25 байтов длиннее, и только первые 3 байта равны в обоих ключах. Вот картина сравнения ключей:
Если мы внимательно посмотрим на эту картинку, то увидим, что ключевая версия openssl имеет какой-то дополнительный 24-байтовый заголовок после 3-го байта. Пока не выяснил, что это такое, но если я объединяю этот жестко закодированный заголовок с выводом, который я получаю из CryptEncodeObject с RSA_CSP_PUBLICKEYBLOB, все работает нормально. Не уверен, что этот заголовок всегда один и тот же или нет.
Используйте RSA_CSP_PUBLICKEYBLOB, как описано в
https://msdn.microsoft.com/en-us/library/windows/desktop/aa378145(v=vs.85).aspx
Я боролся с форматами PUBLICKEYBLOB -> PEM / DER, пока не нашел сообщение о том, как извлечь его из смарт-карты и конвертировать. Суть в том, что MS PUBLICKEYBLOB необходимо удалить первые 32 байта, затем изменить порядок и добавить 02 03 01 00 01 до конца. Это даст вам формат DER. Затем вы можете закодировать в base64, чтобы получить PEM, а затем добавить необходимые строки начала / конца открытого ключа.
Вы можете обратиться к оригинальный пост для фона.