65.9K
CodeProject 正在变化。 阅读更多。
Home

Crypt 库演示 - Microsoft CryptoAPI 库基础

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.83/5 (17投票s)

2014年7月28日

GPL3

2分钟阅读

viewsIcon

31829

downloadIcon

769

本文讨论了密码学的概念及其在确保数据安全中的应用。

引言

简单来说,密码学是应用选定的过程来编码数据,以便可以安全地存储和传输信息。 Microsoft CryptoAPI 允许开发人员通过提供一组灵活的函数来加密或数字签名数据,从而将加密安全构建到他们的应用程序中。 您可以使用密码学来实现许多安全要求,包括

  • 通过对敏感文件进行编码来确保机密性,这样入侵者就无法理解它们;
  • 即使传输介质不安全,也能保证安全通信;
  • 使用数字签名验证消息和数据的来源。

CryptoAPI 支持的基本加密操作是加密、解密和签名。 加密有点像受控的碎片整理:数据就在那里,但它根据加密规则分散。 解密只是加密的逆过程,其中反转加密规则以重新组装数据。 数字签名类似于物理手写签名文档,但有一个显着的改进:伪造数字签名非常非常困难。 在此处,您可以找到有关此主题的更多信息。

Using the Code

主要实现是在 CryptographyExt.hCryptographyExt.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 存储库中。
© . All rights reserved.