如何在CryptoAPI中的注册表中保存加密密钥?

时间:2018-12-12 10:42:39

标签: visual-c++ mfc aes cryptoapi

我是MFC和CryptoAPI的新手。我想对应用程序中的跟踪文件进行加密。 使用密码成功导出了密钥,并且我能够加密数据。加密的数据写入文件中。再次打开文件时,密钥变为0,因为我还没有将其存储在任何地方。

我打算将生成的密钥存储到注册表中。

bool CCrypto::DeriveKey(CString strPassword)
{
    //  Return failure if we don't have a context or hash.
    if(m_hCryptProv == NULL || m_hHash == NULL)
        return false;

    //  If we already have a hash, trash it.
    if(m_hHash)
    {
        CryptDestroyHash(m_hHash);
        m_hHash = NULL;
        if(!CryptCreateHash(m_hCryptProv, CALG_MD5, 0, 0, &m_hHash)) 
            return false;
    }

    //  If we already have a key, destroy it.
    if(m_hKey)
    {
        ::CryptDestroyKey(m_hKey);
        m_hKey = NULL;
    }

    //  Hash the password. This will have a different result in UNICODE mode, as it
    //  will hash the UNICODE string (this is by design, allowing for UNICODE passwords, but
    //  it's important to be aware of this behaviour.
    if(!CryptHashData(m_hHash, (const BYTE*)(LPCSTR)strPassword, strPassword.GetLength() * sizeof(TCHAR), 0)) 
        return false;

    //  Create a session key based on the hash of the password.
    if(!CryptDeriveKey(m_hCryptProv, CALG_RC2, m_hHash, CRYPT_EXPORTABLE, &m_hKey))
        return false;

    HKEY subKey;
    char data[256] = "";
    unsigned long length = 255;
    DWORD disposition;
    char main_key[256] = "Software\\HFS Internal Interface";
    if (RegCreateKeyEx(HKEY_CURRENT_USER, main_key, 0, "", REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &subKey, &disposition) == ERROR_SUCCESS) {
        RegSetValueEx(subKey, "Encryption", 0, REG_SZ, (unsigned char *)m_hKey, length);
    }
    //  And we're done.
    return true;
}

但是当类型m_hKey的{​​{1}}转换为Unicode字符时。我需要在注册表中存储正确的密钥。任何帮助表示赞赏。

1 个答案:

答案 0 :(得分:0)

您序列化密钥的句柄,而不是序列号数据 可能您应该在通过CryptExportKey加密后导出密钥 并通过CryptImportKey解密将其导入

此外,如果您从哈希中获取密钥,为什么不将哈希存储在注册表中,然后再次从此哈希中获取