首页 > 解决方案 > 如何在 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类型HCRYPTKEY转换为 Unicode 字符时。我需要在注册表中存储正确的密钥。任何帮助表示赞赏。

标签: visual-c++mfcaescryptoapi

解决方案


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

此外,如果您从散列中派生密钥,为什么不将散列存储在注册表中,然后再次从该散列中派生它


推荐阅读