0

我正在写一个 CNG 提供程序。具体来说,坚持实现NCryptExportKeyAPI。我正在尝试从硬件密钥管理器转换 EC 密钥(用于签名,ECDSA256)。硬件密钥管理器提供 ASN 格式的密钥。我参考了 MSDN 文档,提到公钥 X 和 Y 值(BCRYPT_ECCKEY_BLOB 结构)是大端格式。但是在关于 stackoverflow 的另一篇文章(从其他地方导入公钥到 CngKey?)中,Magic 值似乎也是大端格式。

我的问题是:

  1. 'magic' 和 'length' 值是否需要采用大端格式?

  2. 如何将大数 X 转换为 big-endian 格式?转换每个字节?

4

3 回答 3

1

您可以这样将 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 进行导入。

于 2019-11-22T10:17:44.920 回答
1

为了从组转换为魔术,您可以轻松地执行此操作(伪代码):

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

您可以使用 Big-Endian 获得 X 和 YBN_bn2bin()

于 2017-08-08T19:37:03.960 回答
0

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.

于 2017-07-27T22:18:30.580 回答