visual-c++ - 如何在 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 字符时。我需要在注册表中存储正确的密钥。任何帮助表示赞赏。
解决方案
您序列化密钥的句柄,而不是密钥数据,您可能应该在加密后通过 CryptExportKey 导出密钥并通过 CryptImportKey 将其导入解密
此外,如果您从散列中派生密钥,为什么不将散列存储在注册表中,然后再次从该散列中派生它
推荐阅读
- laravel - 如果用户成功登录并在 laravel-8 中返回该数据,如何从迁移表中获取特定列数据(角色列)?
- c# - 正则表达式无法检测到,(逗号)
- pandas - 查找哪些列包含/匹配另一列的智能/pythonic方法
- c# - 扫描 DHL 标签时出现问题 Identcode C# XAMARIN EMDK
- macos - macOS11(虚拟机或docker容器)启动时如何设置自动登录
- php - 将下划线 URL 的 PHP 查询转换为破折号/连字符 URL
- javascript - 使用 javascript 的牛顿摇篮。未捕获的类型错误:无法读取未定义 index.js.90 的属性“x”
- android - 在不使用 Play App Signing 的情况下使用 v2 签名方案签署应用程序包
- laravel - 如何在 Laravel 8 中播种 2 个相互关联的表
- java - 如何使用 Selenium + Java 在 Google Chrome 弹出窗口上自动单击“允许”