Cryptography CNG提供商,如何将EC密钥转换为BCRYPT_ECCKEY_BLOB结构?

Cryptography CNG提供商,如何将EC密钥转换为BCRYPT_ECCKEY_BLOB结构?,cryptography,ecdsa,cng,Cryptography,Ecdsa,Cng,我正在写一个CNG供应商。具体来说,在实现NCryptExportKeyAPI时遇到了困难。我正在尝试从硬件密钥管理器转换EC密钥(用于签名,ECDSA256)。h/w密钥管理器提供ASN格式的密钥。我参考了MSDN文档,其中提到公钥X和Y值(BCRYPT_ECCKEY_BLOB结构)采用big-endian格式。但是在另一篇关于stackoverflow()的文章中,神奇的值似乎也是big-endian格式的 我的问题是: “magic”和“length”值是否需要采用big-endian格式

我正在写一个CNG供应商。具体来说,在实现
NCryptExportKey
API时遇到了困难。我正在尝试从硬件密钥管理器转换EC密钥(用于签名,ECDSA256)。h/w密钥管理器提供ASN格式的密钥。我参考了MSDN文档,其中提到公钥X和Y值(BCRYPT_ECCKEY_BLOB结构)采用big-endian格式。但是在另一篇关于stackoverflow()的文章中,神奇的值似乎也是big-endian格式的

我的问题是:

  • “magic”和“length”值是否需要采用big-endian格式

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


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

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


    如果您有一个
    biginger
    实例,那么只需使用
    ToByteArray
    将其保存为字节,然后颠倒字节顺序即可。里面的部分将保持不变。如果该值左边有一个零字节(反转后),那么您也需要去掉该字节。

    魔术用于与常量进行比较。因为它不是一个数字,所以它不是一个大端字节小端字节格式。您应该只使用常量来设置或比较值;它们不一定需要包含任何数字

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


    如果您有一个
    biginger
    实例,那么只需使用
    ToByteArray
    将其保存为字节,然后颠倒字节顺序即可。里面的部分将保持不变。如果值的左边有一个零字节(反转后),那么您也需要去掉该字节。

    为了从group转换为magic,您可以轻松地执行以下操作(伪代码):

    ULONG nid_to_magic___(EC_键*eckey){
    int nid=EC_GROUP_get_curve_name(EC_KEY_get0_GROUP(eckey));
    交换机(nid){
    案例NID_X9_62_prime256v1:
    返回BCRYPT_uuuuuuup256_MAGIC;
    案例NID_secp384r1:
    返回BCRYPT\uuuuuuuup384\u MAGIC;
    案例NID_secp521r1:
    返回BCRYPT_uuuuup521_MAGIC;
    //等等。。。
    }
    //注:似乎魔法数字比NID更“迂腐”;
    } 
    

    您可以使用

    获得大端字节中的X和Y,以便从组转换为魔术。您可以轻松地执行此操作(伪代码):

    ULONG nid_to_magic___(EC_键*eckey){
    int nid=EC_GROUP_get_curve_name(EC_KEY_get0_GROUP(eckey));
    交换机(nid){
    案例NID_X9_62_prime256v1:
    返回BCRYPT_uuuuuuup256_MAGIC;
    案例NID_secp384r1:
    返回BCRYPT\uuuuuuuup384\u MAGIC;
    案例NID_secp521r1:
    返回BCRYPT_uuuuup521_MAGIC;
    //等等。。。
    }
    //注:似乎魔法数字比NID更“迂腐”;
    } 
    

    您可以使用

    在Big-Endian中获得X和Y,您可以这样将EC-key转换为BCRYPT\u ECCKEY\u 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进行导入。

    您可以这样将EC key转换为BCRYPT\u ECCKEY\u 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进行导入