Crypt 库演示 - Microsoft CryptoAPI 库基础






4.83/5 (17投票s)
本文讨论了密码学的概念及其在确保数据安全中的应用。
引言
简单来说,密码学是应用选定的过程来编码数据,以便可以安全地存储和传输信息。 Microsoft CryptoAPI
允许开发人员通过提供一组灵活的函数来加密或数字签名数据,从而将加密安全构建到他们的应用程序中。 您可以使用密码学来实现许多安全要求,包括
- 通过对敏感文件进行编码来确保机密性,这样入侵者就无法理解它们;
- 即使传输介质不安全,也能保证安全通信;
- 使用数字签名验证消息和数据的来源。
CryptoAPI
支持的基本加密操作是加密、解密和签名。 加密有点像受控的碎片整理:数据就在那里,但它根据加密规则分散。 解密只是加密的逆过程,其中反转加密规则以重新组装数据。 数字签名类似于物理手写签名文档,但有一个显着的改进:伪造数字签名非常非常困难。 在此处,您可以找到有关此主题的更多信息。
Using the Code
主要实现是在 CryptographyExt.h 和 CryptographyExt.cpp 文件中完成的,如下所示
BOOL GetChecksumBuffer(ALG_ID nAlgorithm, LPBYTE lpszOutputBuffer, DWORD& dwOutputLength, LPBYTE lpszInputBuffer, DWORD dwInputLength);
使用指定的算法计算给定二进制缓冲区的哈希码;BOOL GetChecksumString(ALG_ID nAlgorithm, CString& strResult, CString strBuffer);
使用指定的算法计算给定CString
的哈希码;BOOL GetChecksumFile(ALG_ID nAlgorithm, CString& strResult, CString strPathName);
使用指定的算法计算给定文件的哈希码;BOOL EncryptBuffer(ALG_ID nAlgorithm, LPBYTE lpszOutputBuffer, DWORD& dwOutputLength, LPBYTE lpszInputBuffer, DWORD dwInputLength, LPBYTE lpszSecretKey, DWORD dwSecretKey);
使用指定的算法加密给定的二进制缓冲区;BOOL EncryptFile(ALG_ID nAlgorithm, CString strOutputName, CString strInputName, LPBYTE lpszSecretKey, DWORD dwSecretKey);
使用指定的算法加密给定的文件;BOOL DecryptBuffer(ALG_ID nAlgorithm, LPBYTE lpszOutputBuffer, DWORD& dwOutputLength, LPBYTE lpszInputBuffer, DWORD dwInputLength, LPBYTE lpszSecretKey, DWORD dwSecretKey);
使用指定的算法解密给定的二进制缓冲区;BOOL DecryptFile(ALG_ID nAlgorithm, CString strOutputName, CString strInputName, LPBYTE lpszSecretKey, DWORD dwSecretKey);
使用指定的算法解密给定的文件;- 密钥辅助函数:
CString GetComputerID();
BOOL GetChecksumBuffer(ALG_ID nAlgorithm, LPBYTE lpszOutputBuffer,
DWORD& dwOutputLength, LPBYTE lpszInputBuffer, DWORD dwInputLength)
{
BOOL retVal = FALSE;
ASSERT(lpszOutputBuffer != NULL);
ASSERT(dwOutputLength != 0);
ASSERT(lpszInputBuffer != NULL);
ASSERT(dwInputLength != 0);
HCRYPTPROV hCryptProv = NULL;
HCRYPTHASH hCryptHash = NULL;
if (CryptAcquireContext(&hCryptProv, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT))
{
if (CryptCreateHash(hCryptProv, nAlgorithm, NULL, 0, &hCryptHash))
{
if (CryptHashData(hCryptHash, lpszInputBuffer, dwInputLength, 0))
{
if (CryptGetHashParam(hCryptHash, HP_HASHVAL,
lpszOutputBuffer, &dwOutputLength, 0))
{
retVal = TRUE;
}
else
{
TraceLastError(CRYPT_LIBRARY_NAME, _T("CryptGetHashParam"),
GetLastError());
}
}
else
{
TraceLastError(CRYPT_LIBRARY_NAME, _T("CryptHashData"), GetLastError());
}
VERIFY(CryptDestroyHash(hCryptHash));
}
else
{
TraceLastError(CRYPT_LIBRARY_NAME, _T("CryptCreateHash"), GetLastError());
}
VERIFY(CryptReleaseContext(hCryptProv, 0));
}
else
{
TraceLastError(CRYPT_LIBRARY_NAME, _T("CryptAcquireContext"), GetLastError());
}
return retVal;
}
BOOL EncryptBuffer(ALG_ID nAlgorithm, LPBYTE lpszOutputBuffer, DWORD& dwOutputLength,
LPBYTE lpszInputBuffer, DWORD dwInputLength, LPBYTE lpszSecretKey, DWORD dwSecretKey)
{
BOOL retVal = FALSE;
DWORD dwHowManyBytes = dwInputLength;
ASSERT(lpszOutputBuffer != NULL);
ASSERT(dwOutputLength != 0);
ASSERT(lpszInputBuffer != NULL);
ASSERT(dwInputLength != 0);
ASSERT(lpszSecretKey != NULL);
ASSERT(dwSecretKey != 0);
HCRYPTPROV hCryptProv = NULL;
HCRYPTHASH hCryptHash = NULL;
HCRYPTKEY hCryptKey = NULL;
::CopyMemory(lpszOutputBuffer, lpszInputBuffer, dwHowManyBytes);
if (CryptAcquireContext(&hCryptProv, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT))
{
if (CryptCreateHash(hCryptProv, CALG_MD5, NULL, 0, &hCryptHash))
{
if (CryptHashData(hCryptHash, lpszSecretKey, dwSecretKey, 0))
{
if (CryptDeriveKey(hCryptProv, nAlgorithm,
hCryptHash, CRYPT_EXPORTABLE, &hCryptKey))
{
if (CryptEncrypt(hCryptKey, NULL, TRUE, 0,
lpszOutputBuffer, &dwHowManyBytes, dwOutputLength))
{
dwOutputLength = dwHowManyBytes;
retVal = TRUE;
}
else
{
TraceLastError(CRYPT_LIBRARY_NAME, _T("CryptEncrypt"),
GetLastError());
}
VERIFY(CryptDestroyKey(hCryptKey));
}
else
{
TraceLastError(CRYPT_LIBRARY_NAME, _T("CryptDeriveKey"),
GetLastError());
}
}
else
{
TraceLastError(CRYPT_LIBRARY_NAME, _T("CryptHashData"), GetLastError());
}
VERIFY(CryptDestroyHash(hCryptHash));
}
else
{
TraceLastError(CRYPT_LIBRARY_NAME, _T("CryptCreateHash"), GetLastError());
}
VERIFY(CryptReleaseContext(hCryptProv, 0));
}
else
{
TraceLastError(CRYPT_LIBRARY_NAME, _T("CryptAcquireContext"), GetLastError());
}
return retVal;
}
BOOL DecryptBuffer(ALG_ID nAlgorithm, LPBYTE lpszOutputBuffer, DWORD& dwOutputLength,
LPBYTE lpszInputBuffer, DWORD dwInputLength, LPBYTE lpszSecretKey, DWORD dwSecretKey)
{
BOOL retVal = FALSE;
DWORD dwHowManyBytes = dwInputLength;
ASSERT(lpszOutputBuffer != NULL);
ASSERT(dwOutputLength != 0);
ASSERT(lpszInputBuffer != NULL);
ASSERT(dwInputLength != 0);
ASSERT(lpszSecretKey != NULL);
ASSERT(dwSecretKey != 0);
HCRYPTPROV hCryptProv = NULL;
HCRYPTHASH hCryptHash = NULL;
HCRYPTKEY hCryptKey = NULL;
::CopyMemory(lpszOutputBuffer, lpszInputBuffer, dwHowManyBytes);
if (CryptAcquireContext(&hCryptProv, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT))
{
if (CryptCreateHash(hCryptProv, CALG_MD5, NULL, 0, &hCryptHash))
{
if (CryptHashData(hCryptHash, lpszSecretKey, dwSecretKey, 0))
{
if (CryptDeriveKey(hCryptProv, nAlgorithm,
hCryptHash, CRYPT_EXPORTABLE, &hCryptKey))
{
if (CryptDecrypt(hCryptKey, NULL, TRUE, 0,
lpszOutputBuffer, &dwHowManyBytes))
{
dwOutputLength = dwHowManyBytes;
retVal = TRUE;
}
else
{
TraceLastError(CRYPT_LIBRARY_NAME, _T("CryptDecrypt"),
GetLastError());
}
VERIFY(CryptDestroyKey(hCryptKey));
}
else
{
TraceLastError(CRYPT_LIBRARY_NAME, _T("CryptDeriveKey"),
GetLastError());
}
}
else
{
TraceLastError(CRYPT_LIBRARY_NAME, _T("CryptHashData"), GetLastError());
}
VERIFY(CryptDestroyHash(hCryptHash));
}
else
{
TraceLastError(CRYPT_LIBRARY_NAME, _T("CryptCreateHash"), GetLastError());
}
VERIFY(CryptReleaseContext(hCryptProv, 0));
}
else
{
TraceLastError(CRYPT_LIBRARY_NAME, _T("CryptAcquireContext"), GetLastError());
}
return retVal;
}
历史
- 版本 1.00 (2014 年 7 月 27 日)
- 首次发布
- 相同版本 (2023 年 3 月 31 日)
- 将源代码移动到 GitHub
- 版本 1.01 (2023 年 6 月 25 日)
- 使用 GPLv3 公告更新“关于”对话框
- 用 PJ Naughter 的
CHLinkCtrl
库替换旧的CHyperlinkStatic
类
- 版本 1.02 (2023 年 10 月 19 日)
- 更新“关于”对话框(电子邮件和网站)
- 添加社交媒体链接:Twitter、LinkedIn、Facebook 和 Instagram
- 添加 GitHub 存储库的问题、讨论和 Wiki 的快捷方式
- 相同版本 (2024 年 1 月 20 日) - 将 ReleaseNotes.html 和 SoftwareContextRegister.html 添加到 GitHub 存储库中。