CNG provider, how to convert an EC key to BCRYPT_ECCKEY_BLOB structure?

吃可爱长大的小学妹 提交于 2019-12-12 04:46:59

问题


I am writing a CNG provider. Specifically, stuck on implementing NCryptExportKey API. I am trying to convert an EC key (for signing, ECDSA256) from a hardware key manager. The h/w keymanager provides key in ASN format. I referred to MSDN documentation, it's mentioned that public key X and Y values(of BCRYPT_ECCKEY_BLOB structure) are in big-endian format. But in another post on stackoverflow (Import a Public key from somewhere else to CngKey?), the Magic value also seems to be in big-endian format.

My Questions are:

  1. Are the 'magic' and 'length' values need to be in big-endian format?

  2. How a big number X to be converted to big-endian format? Convert each byte?


回答1:


You convert EC key to BCRYPT_ECCKEY_BLOB by like this. We should ignore the first byte from EC key because it just represent compressed/uncompressed format.

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);

now use bycrtptKey for importing.




回答2:


The magic is used to compare against constants. As it isn't a number it isn't in a big endian or little endian format. You should just use the constants to either set or compare the values; they do not necessarily need to contain any number.

The length is an ULONG and since .NET unfortunately is based on little endian it is undoubtedly also stored as little endian. Normally you don't care; just use an ULONG to set or retrieve it.

If you have a BigInteger instance then you can simply save it as bytes using ToByteArray and then reverse the order of the bytes. The bits inside will stay the same. If the value has a zero byte to the left (after reversing) then you need to strip that byte as well.




回答3:


In order to convert from group to magic you can easily do this (pseudo code):

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";
} 

You can get X and Y in Big-Endian using BN_bn2bin()



来源:https://stackoverflow.com/questions/45350583/cng-provider-how-to-convert-an-ec-key-to-bcrypt-ecckey-blob-structure

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!