【问题标题】:How to create a symmetric key for CryptDecrypt using raw hex key values in Windows CryptoAPI?如何使用 Windows CryptoAPI 中的原始十六进制密钥值为 CryptDecrypt 创建对称密钥?
【发布时间】:2019-06-06 20:56:46
【问题描述】:

经过多次反复试验,我能够使用 Windows CryptoAPI 使用 AES-256 密钥成功加密文件。

加密程序执行以下操作:

  • 将块长度固定为 128 位 (AES)
  • 生成 AES-256-CBC 密钥 (CryptGenKey)
  • 使用此密钥加密文件 (CryptEncrypt)

现在为了解密文件,我想使用原始十六进制值格式的密钥。例如,我有这个键:

76FD3DBDFA2AA07113A227D9E0311DC5BC7FA78A7E4FC3CE63919B9C49DC4F06

(请注意,此密钥是随机的generated online 仅作为示例,不会在任何地方用于保护任何东西)

我所拥有的只是密钥的原始十六进制值,如上所示。所以我需要能够将它提供给CryptDecrypt 函数并解密数据。 问题是:

CryptDecrypt expects the key to be sent in as an HCRYPTKEY data type。但我所拥有的只是一个以这种格式存储的密钥:

wchar_t* key = argv[1]  //reading the key in hex format as an argument

我尝试过的:

CryptDeriveKey 从基值派生 HCRYPTKEY 格式的密钥。但是,CryptDeriveKey 不会接受我目前拥有的十六进制值格式的密钥,因为它反过来需要 HCRYPTHASH 格式的密钥。

此时,我不确定如何使用我拥有的原始十六进制值作为 CryptDecrypt 解密数据的密钥。我知道有可能,只是不知道怎么去。

由于我不会深入探讨的原因,我必须从我拥有的原始十六进制值中派生密钥(与任何其他密钥格式,如字节数组相反)并将其提供给CryptDecrypt 解密数据。

【问题讨论】:

    标签: encryption cryptography cryptoapi


    【解决方案1】:

    您应该使用CryptImportKey function 导入密钥。

    BOOL CryptImportKey(
      HCRYPTPROV hProv,
      const BYTE *pbData,
      DWORD      dwDataLen,
      HCRYPTKEY  hPubKey,
      DWORD      dwFlags,
      HCRYPTKEY  *phKey
    );
    

    hProv - 使用 CryptAcquireContext 函数获得的 CSP 的句柄。
    hPubKey - 在您的情况下必须为 0。
    dwFlags - 在您的情况下必须为 0。
    phKey - CryptDecrypt 预期的结果密钥。

    这里有一些棘手的部分。 pbData 必须包含BLOBHEADER 结构,后跟键值。

    typedef struct _PUBLICKEYSTRUC {
      BYTE   bType;
      BYTE   bVersion;
      WORD   reserved;
      ALG_ID aiKeyAlg;
    } BLOBHEADER, PUBLICKEYSTRUC;
    
    bType = PLAINTEXTKEYBLOB (0x08) - in your case  
    bVersion = CUR_BLOB_VERSION (0x02) 
    reserved = 0  
    aiKeyAlg = algorithm id which you used in CryptGenKey
    

    示例代码:

    BYTE key_value[] = { 0x76, 0xFD, 0x3D, 0xBD, 0xFA, 0x2A, 0xA0, 0x71, 0x13, 0xA2, 0x27, 0xD9, 0xE0, 0x31, 0x1D, 0xC5, 
        0xBC, 0x7F, 0xA7, 0x8A, 0x7E, 0x4F, 0xC3, 0xCE, 0x63, 0x91, 0x9B, 0x9C, 0x49, 0xDC, 0x4F, 0x06 };
    BLOBHEADER bh;
    bh.bType = PLAINTEXTKEYBLOB;
    bh.bVersion = CUR_BLOB_VERSION;
    bh.reserved = 0;
    bh.aiKeyAlg = CALG_AES_256;
    
    DWORD dwDataLen = sizeof(key_value) + sizeof(bh);
    BYTE* pbData = (BYTE*)malloc(dwDataLen);
    BYTE* ptr = pbData;
    memcpy(ptr, (BYTE*)&bh, sizeof(bh));
    ptr += sizeof(bh);
    memcpy(ptr, key_value, sizeof(key_value));
    if (!CryptImportKey(hProv, pbData, dwDataLen, 0, 0, &hKey)) {
        return GetLastError();
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-05-07
      • 2019-12-20
      • 2015-02-08
      • 2019-06-11
      • 2011-04-21
      • 2019-11-30
      • 1970-01-01
      相关资源
      最近更新 更多