2017-07-27 65 views
0

我正在写一个CNG供应商。具体来说,坚持实施NCryptExportKey API。我正尝试从硬件密钥管理器转换EC密钥(用于签名,ECDSA256)。 h/w密钥管理器以ASN格式提供密钥。我提到了MSDN文档,它提到了公钥X和Y值(BCRYPT_ECCKEY_BLOB结构)是以big-endian格式。但在另一篇文章中,stackoverflow(Import a Public key from somewhere else to CngKey?),魔法值也似乎是big-endian格式。CNG提供程序,如何将EC密钥转换为BCRYPT_ECCKEY_BLOB结构?

我的问题是:

  1. 是 '魔法' 和 '长度' 值需要在big-endian格式?

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

回答

0

魔法是用来比较常数。因为它不是一个数字,所以它不是大尾数格式的。您应该只使用常量来设置或比较值;他们不一定需要包含任何数字。

长度是一个ULONG,因为不幸的是.NET基于小端,它无疑也存储为小端。通常你不在乎;只需使用ULONG来设置或检索它。

如果您有BigInteger实例,则可以使用ToByteArray将其简单地保存为字节,然后颠倒字节的顺序。里面的位将保持不变。如果该值左侧为零字节(反转后),则还需要删除该字节。

0

为了从组转化为魔,你可以很容易地做到这一点(伪代码):

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使用BN_bn2bin()

相关问题