CryptBinaryToString не выводит ожидаемый открытый ключ - PullRequest
1 голос
/ 14 мая 2019

Я пытаюсь вывести исходную форму base64 импортированного открытого ключа RSA, используя функции Windows CryptoAPI.Используя CryptBinaryToString с флагом CRYPT_STRING_BASE64HEADER, выходной заголовок будет читать «BEGIN CERTIFICATE» вместо ожидаемого «BEGIN PUBLIC KEY».

(РЕДАКТИРОВАТЬ: я не выделил эту часть своей проблемы) Кроме того, результирующий открытый ключ, кажется, отличается от оригинала.

Не станет ли это проблематичным, если бы я экспортировалвывод и реимпорт это?Если так, что я делаю не так?

Вот как был импортирован открытый ключ.

Открытый ключ хранится в файле pubkey.pem в следующем формате PEM:

-----BEGIN PUBLIC KEY-----
[REDACTED]
-----END PUBLIC KEY-----

Файл считывается в буфер с помощью CreateFile / ReadFile.PEM преобразован в двоичный файл с использованием CryptStringToBinaryA.Двоичный файл декодируется в X509_PUBLIC_KEY_INFO с использованием CryptDecodeObjectEx.Структура PubKeyInfo декодируется в RSA_CSP_PUBLICKEYBLOB (та же функция, что и выше).

Эта часть прекрасно работает (можно импортировать ключ и шифровать данные с помощью CryptImportKey, CryptEncrypt и т. Д.).

Вот код, которыйЯ собрал, чтобы попытаться вернуть сырой блоб обратно в формат base64 PEM.Я удалил большинство проверок ошибок, чтобы сохранить головные боли.

pbTmp и cbTmp - это временный буфер для хранения вывода и размера соответственно.pBinaryKey - это необработанный BLOB-объект открытого ключа (импортированный из более ранних версий). pBuffer - это выходной буфер (предполагается, что он имеет правильный размер). ulDataLen - это размер выходного буфера

CryptEncodeObjectEx(X509_ASN_ENCODING, RSA_CSP_PUBLICKEYBLOB, pBinaryKey, 0, NULL, NULL, &cbTmp)
pbTmp = malloc(cbTmp);
CryptEncodeObjectEx(X509_ASN_ENCODING, RSA_CSP_PUBLICKEYBLOB, pBinaryKey, 0, NULL, pbTmp, &cbTmp)
CryptBinaryToStringA(pbTmp, cbTmp, CRYPT_STRING_BASE64HEADER, NULL, &ulDataLen)
CryptBinaryToStringA(pbTmp, cbTmp, CRYPT_STRING_BASE64HEADER, pBuffer, &ulDataLen)

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

-----BEGIN CERTIFICATE-----
[REDACTED; DIFFERENT FROM ORIGINAL PUBLIC KEY]
-----END CERTIFICATE-----

1 Ответ

0 голосов
/ 15 мая 2019

Согласно документу :

CRYPT_STRING_BASE64HEADER (0x00000000): Base64, с сертификатом начальные и конечные заголовки.

Ожидаемый заголовок: «НАЧАТЬ СЕРТИФИКАТ». И нет никакой другой поддержки параметра флага для «НАЧАЛА ПУБЛИЧНОГО КЛЮЧА». Как говорит @Jonathan Potter, вы всегда можете использовать флаг CRYPT_STRING_BASE64 для кодирования без заголовков, а затем сами добавить правильный заголовок.

А вот еще один ответ о получении PUBILC из сертификата с помощью openssl.

...