Обновление/генерация ключей RSA

Доброе время суток. Прошу помочь разобраться с ключами RSA (как я понял). Пришел на новое место работы стажером. Дали задание обновить программу, где используется шифрование. Решил заодно, как я понял, обновить ключи или что-то типа того на новые. Не могу понять как это сделать.

Вот кусок кода где указан ключ:

STATIC BYTE PublicKey[4096] = "\x07\x02\x00\x00\x00\xA4\x00\x00\x52\x53\x41\x32\x00\x10\x00\x00\x01\x00\x01\x00\xB5\xB4\xDC\x55\xFE............";

Вот функция, где используется ключ:

pCryptImportKey(CryptoProvider, PublicKey, sizeof(PublicKey), 0, 0, &RsaPublicKey);

Вопрос заключается в следующем: как обновить переменную PublicKey на свое значение. Возможно даже в таком же формате (\x02\xA4 и т.д.). Я так понял это ключ RSA, но не могу допереть как обновить ключ на свой.


Ответы (1 шт):

Автор решения: Pak Uula

То, что вы нам показали - это приватный ключ. Он закодирован как структура данных PUBLICKEYSTRUC (aka BLOBHEADER)

Первый байт 0x07 означает The key is a public/private key pair. Вызов CryptImportKey(CryptoProvider, PublicKey, sizeof(PublicKey), 0, 0, &RsaPublicKey); генерирует из приватного ключа публичный и сохранаяет его в переменную RsaPublicKey

Вам нужно точно выяснить задачу. Нельзя просто так брать и обновлять приватные ключи, от этого посыпятся все зависимости, которые завязаны на сертификаты и публичный ключ.

Но если вам интересно, то делается это так.

Функцией CryptGenKey генерируете приватный ключ для алгоритма CALG_RSA_KEYX. Параметр dwFlags должен быть CRYPT_EXPORTABLE | (4096 << 16) - длина ключа передаётся как верхние 16 бит параметра dwFlags.

Насчет длины 4096 я усомнился. Посчитайте, сколько байтов в строке PublicKey и вычтите 8 байтов заголовка, это будет длина ключа в байтах. Умножте получившееся число на 8 - будет длина в битах.

Откуда я узнал, что идентификатор CALG_RSA_KEYX. Это байты 4-8 в вашем приватном ключе: \x00\xA4\x00\x00\ или 0x0000a400 в little-endian формате.

Затем функцией CryptExportKey вы экспортируете сгененированный ключ в бинарный формат:

  • Параметр hExpKey равен 0, так как в вашем примере ключ импортируется без расшифровки.
  • Параметр dwBlobType равен PRIVATEKEYBLOB
  • Параметр dwFlags равен 0

Если всё пройдёт хорошо, в памяти по указателю pbData будет лежать сгенерированный ключ, а в параметре pdwDataLen будет длина ключа. Вам достаточно распечатать его в шестнадцатиричном формате \x00 и готово. Можно подставить сгененированную строку вместо STATIC BYTE PublicKey[4096]

PS. Размер ключа BYTE[4096] - это какая-то феерическая ... выдумка. Размер ключа 4096 БИТ, то есть 512 байт, плюс структура BLOBHEADER рамером 8 байт. Итого 520 байт. Да ещё хранение в строковом виде...

Я впечатлён.

→ Ссылка