Поставщик CNG, как преобразовать ключ EC в структуру BCRYPT_ECCKEY_BLOB?

Я пишу провайдер CNG. В частности, застрял на реализации NCryptExportKey API. Я пытаюсь преобразовать ключ EC (для подписи, ECDSA256) из аппаратного диспетчера ключей. H /w keymanager предоставляет ключ в формате ASN. Я ссылался на документацию MSDN, упоминалось, что значения X и Y открытого ключа (в структуре BCRYPT_ECCKEY_BLOB) представлены в формате с прямым порядком байтов. Но в другом посте о stackru ( импортировать открытый ключ откуда-то еще в CngKey?) Значение Magic также представляется в формате с прямым порядком байтов.

Мои вопросы:

  1. Должны ли значения 'magic' и 'length' быть в формате с прямым порядком байтов?

  2. Как большое число X будет преобразовано в формат с прямым порядком байтов? Конвертировать каждый байт?

2 ответа

Чтобы преобразовать группу в магию, вы можете легко сделать это (псевдокод):

ULONG nid_to_magic_<public|private>_<ecdsa|ecdh> (EC_KEY * eckey) {
 int nid = EC_GROUP_get_curve_name(EC_KEY_get0_group(eckey));
 switch(nid){
   case NID_X9_62_prime256v1:
       return BCRYPT_<ECDH | ECDSA>_<PUBLIC | PRIVATE>_P256_MAGIC;
   case NID_secp384r1:
       return BCRYPT_<ECDH | ECDSA>_<PUBLIC | PRIVATE>_P384_MAGIC;
   case NID_secp521r1:
       return BCRYPT_<ECDH | ECDSA>_<PUBLIC | PRIVATE>_P521_MAGIC;

  //And so on...
  }
  //Note: it seems that the magic number is more "pedantic than NID";
} 

Вы можете получить X и Y в Big-Endian, используя BN_bn2bin()

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

BCRYPT_ECCKEY_BLOB eccBlobHeader;
PCHAR bycrtptKey;
eccBlobHeader.dwMagic = BCRYPT_ECDH_PUBLIC_P384_MAGIC;  
eccBlobHeader.cbKey = 48;//size of EC key(without 1st byte)
memcpy(bycrtptKey, &eccBlobHeader, 8);//copying 8bytes header blob
memcpy(bycrtptKey+ 8,publicKeyFromOtherParty+1,publicKeyFromOtherPartySize- 1);

теперь используйте bycrtptKey для импорта.

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

Длина ULONG и, к сожалению,.NET основана на порядке с прямым порядком байтов, она, несомненно, также хранится как последовательность с прямым порядком байтов. Обычно тебе все равно; просто используйте ULONG, чтобы установить или получить его.

Если у тебя есть BigInteger экземпляр, то вы можете просто сохранить его как байты, используя ToByteArray и затем обратный порядок байтов. Биты внутри останутся прежними. Если значение имеет нулевой байт слева (после реверса), то вам также необходимо удалить этот байт.

Другие вопросы по тегам