天天看點

windows自帶的加密庫實作加密

//************************************
    // 函數名:CEncryptionDlg::CalculateHash
    // 傳回類型:BOOL
    // 功能:    計算hash值
    // 參數1:BYTE *pData 需要計算哈希值的資料
    // 參數2:DWORD dwDataLength 需要計算哈希值的資料長度
    // 參數3:ALG_ID algHashType 需要計算哈希值的資料的類型
    // 參數4:BYTE **ppHashData 計算出來的哈希資料
    // 參數5:DWORD *pdwHashDataLength 計算出來的哈希資料長度
    //************************************
    BOOL CalculateHash(BYTE *pData, DWORD dwDataLength, ALG_ID algHashType, BYTE **ppHashData, DWORD *pdwHashDataLength);

    //************************************
    // 函數名:CEncryptionDlg::AesEncrypt
    // 傳回類型:BOOL
    // 功能:    AES加密
    // 參數1:BYTE *pPassword 密鑰
    // 參數2:DWORD dwPasswordLength 密鑰長度
    // 參數3:BYTE *pData 需要AES加密的資料
    // 參數4:DWORD &dwDataLength 需要AES加密的資料長度
    // 參數5:DWORD dwBufferLength  緩沖區長度
    //************************************
    BOOL AesEncrypt(BYTE *pPassword, DWORD dwPasswordLength, BYTE *pData, DWORD &dwDataLength, DWORD dwBufferLength);

    //************************************
    // 函數名:CEncryptionDlg::AesDecrypt
    // 傳回類型:BOOL
    // 功能:    AES解密
    // 參數1:BYTE *pPassword 密鑰
    // 參數2:DWORD dwPasswordLength 密鑰長度
    // 參數3:BYTE *pData 需要AES解密的資料
    // 參數4:DWORD &dwDataLength 需要AES解密的資料長度
    //************************************
    BOOL AesDecrypt(BYTE *pPassword, DWORD dwPasswordLength, BYTE *pData, DWORD &dwDataLength);

    //************************************
    // 函數名:CEncryptionDlg::GenerateKey
    // 傳回類型:BOOL
    // 功能:    生成公鑰和私鑰
    // 參數1:BYTE **ppPublicKey 公鑰
    // 參數2:DWORD *pdwPublicKeyLength 公鑰長度
    // 參數3:BYTE **ppPrivateKey 私鑰
    // 參數4:DWORD *pdwPrivateKeyLength 私鑰長度
    //************************************
    BOOL GenerateKey(BYTE **ppPublicKey, DWORD *pdwPublicKeyLength, BYTE **ppPrivateKey, DWORD *pdwPrivateKeyLength);

    //************************************
    // 函數名:CEncryptionDlg::RsaEncrypt
    // 傳回類型:BOOL
    // 功能:    RAS加密
    // 參數1:BYTE *pPublicKey    公鑰
    // 參數2:DWORD dwPublicKeyLength    公鑰長度
    // 參數3:BYTE *pData    需要加密的資料
    // 參數4:DWORD &dwDataLength    需要加密的資料長度
    // 參數5:DWORD dwBufferLength    緩沖區長度
    //************************************
    BOOL RsaEncrypt(BYTE *pPublicKey, DWORD dwPublicKeyLength, BYTE *pData, DWORD &dwDataLength, DWORD dwBufferLength);

    //************************************
    // 函數名:CEncryptionDlg::RsaDecrypt
    // 傳回類型:BOOL
    // 功能:     RAS解密
    // 參數1:BYTE **ppPrivateKey 私鑰
    // 參數2:DWORD *pdwPrivateKeyLength 私鑰長度
    // 參數3:BYTE *pData    需要解密的資料
    // 參數4:DWORD &dwDataLength    需要解密的資料長度
    //************************************
    BOOL RsaDecrypt(BYTE *pPrivateKey, DWORD dwProvateKeyLength, BYTE *pData, DWORD &dwDataLength);      
//計算hash值
BOOL CEncryptionDlg::CalculateHash(BYTE *pData, DWORD dwDataLength, ALG_ID algHashType, BYTE **ppHashData, DWORD *pdwHashDataLength)
{
    BOOL bRet = FALSE;
    HCRYPTPROV hCryptProv = NULL;
    HCRYPTHASH hCryptHash = NULL;
    DWORD dwTemp = 0;
    DWORD dwHashDataLength = 0;
    BYTE* pHashData = NULL;

    // 獲得指定CSP的密鑰容器的句柄
    bRet = ::CryptAcquireContext(&hCryptProv, NULL, NULL, PROV_RSA_AES, CRYPT_VERIFYCONTEXT);
    if (FALSE == bRet)
    {
        MessageBox(_T("CryptAcquireContext Error\r\n"));
        return FALSE;
    }

    // 建立一個HASH對象, 指定HASH算法
    bRet = ::CryptCreateHash(hCryptProv, algHashType, NULL, NULL, &hCryptHash);
    if (FALSE == bRet)
    {
        MessageBox(_T("CryptCreateHash Error\r\n"));
        CryptReleaseContext(hCryptProv, 0);
        return FALSE;
    }

    // 計算HASH資料
    bRet = ::CryptHashData(hCryptHash, pData, dwDataLength, 0);
    if (FALSE == bRet)
    {
        MessageBox(_T("CryptHashData Error\r\n"));
        CryptDestroyHash(hCryptHash);
        CryptReleaseContext(hCryptProv, 0);
        return FALSE;
    }

    // 擷取HASH結果的大小
    dwTemp = sizeof(dwHashDataLength);
    bRet = ::CryptGetHashParam(hCryptHash, HP_HASHSIZE, (BYTE *)(&dwHashDataLength), &dwTemp, 0);
    if (FALSE == bRet)
    {
        MessageBox(_T("CryptGetHashParam Error\r\n"));
        CryptDestroyHash(hCryptHash);
        CryptReleaseContext(hCryptProv, 0);
        return FALSE;
    }

    // 申請記憶體
    pHashData = new BYTE[dwHashDataLength]{ 0 };
    if (NULL == pHashData)
    {
        MessageBox(_T("new Error\r\n"));
        CryptDestroyHash(hCryptHash);
        CryptReleaseContext(hCryptProv, 0);
        return FALSE;
    }

    // 擷取HASH結果資料
    bRet = ::CryptGetHashParam(hCryptHash, HP_HASHVAL, pHashData, &dwHashDataLength, 0);
    if (FALSE == bRet)
    {
        MessageBox(_T("CryptGetHashParam Error\r\n"));
        delete[] pHashData;
        pHashData = NULL;
        CryptDestroyHash(hCryptHash);
        CryptReleaseContext(hCryptProv, 0);
        return FALSE;
    }

    // 傳回資料
    *ppHashData = pHashData;
    *pdwHashDataLength = dwHashDataLength;

    // 釋放關閉
    CryptDestroyHash(hCryptHash);
    CryptReleaseContext(hCryptProv, 0);

    return TRUE;
}

// AES加密
BOOL CEncryptionDlg::AesEncrypt(BYTE *pPassword, DWORD dwPasswordLength, BYTE *pData, DWORD &dwDataLength, DWORD dwBufferLength)
{
    BOOL bRet = TRUE;
    HCRYPTPROV hCryptProv = NULL;
    HCRYPTHASH hCryptHash = NULL;
    HCRYPTKEY hCryptKey = NULL;

    do {
        // 擷取CSP句柄
        bRet = ::CryptAcquireContext(&hCryptProv, NULL, NULL, PROV_RSA_AES, CRYPT_VERIFYCONTEXT);
        if (FALSE == bRet)
        {
            MessageBox(_T("CryptAcquireContext Error\r\n"));
            break;
        }

        // 建立HASH對象
        bRet = ::CryptCreateHash(hCryptProv, CALG_MD5, NULL, 0, &hCryptHash);
        if (FALSE == bRet)
        {
            MessageBox(_T("CryptCreateHash Error\r\n"));
            break;
        }

        // 對密鑰進行HASH計算 計算出密鑰的MD5值
        bRet = ::CryptHashData(hCryptHash, pPassword, dwPasswordLength, 0);
        if (FALSE == bRet)
        {
            MessageBox(_T("CryptHashData Error\r\n"));
            break;
        }

        // 使用HASH來生成密鑰
        bRet = ::CryptDeriveKey(hCryptProv, CALG_AES_128, hCryptHash, CRYPT_EXPORTABLE, &hCryptKey);
        if (FALSE == bRet)
        {
            MessageBox(_T("CryptDeriveKey Error\r\n"));
            break;
        }
        // 加密資料
        bRet = ::CryptEncrypt(hCryptKey, NULL, TRUE, 0, pData, &dwDataLength, dwBufferLength);
        if (FALSE == bRet)
        {
            MessageBox(_T("CryptEncrypt Error\r\n"));
            break;
        }
    } while (FALSE);

    // 關閉釋放
    if (hCryptKey)
    {
        CryptDestroyKey(hCryptKey);
    }
    if (hCryptHash)
    {
        CryptDestroyHash(hCryptHash);
    }
    if (hCryptProv)
    {
        CryptReleaseContext(hCryptProv, 0);
    }

    return bRet;
}

// AES解密
BOOL CEncryptionDlg::AesDecrypt(BYTE *pPassword, DWORD dwPasswordLength, BYTE *pData, DWORD &dwDataLength)
{
    // 變量
    BOOL bRet = TRUE;
    HCRYPTPROV hCryptProv = NULL;
    HCRYPTHASH hCryptHash = NULL;
    HCRYPTKEY hCryptKey = NULL;

    do
    {
        // 擷取CSP句柄
        bRet = ::CryptAcquireContext(&hCryptProv, NULL, NULL, PROV_RSA_AES, CRYPT_VERIFYCONTEXT);
        if (FALSE == bRet)
        {
            MessageBox(_T("CryptAcquireContext Error\r\n"));
            break;
        }

        // 建立HASH對象
        bRet = ::CryptCreateHash(hCryptProv, CALG_MD5, NULL, 0, &hCryptHash);
        if (FALSE == bRet)
        {
            MessageBox(_T("CryptCreateHash Error\r\n"));
            break;
        }

        // 對密鑰進行HASH計算
        bRet = ::CryptHashData(hCryptHash, pPassword, dwPasswordLength, 0);
        if (FALSE == bRet)
        {
            MessageBox(_T("CryptCreateHash Error\r\n"));
            break;
        }

        // 使用HASH來生成密鑰
        bRet = ::CryptDeriveKey(hCryptProv, CALG_AES_128, hCryptHash, CRYPT_EXPORTABLE, &hCryptKey);
        if (FALSE == bRet)
        {
            MessageBox(_T("CryptDeriveKey Error\r\n"));
            break;
        }

        // 解密資料
        bRet = ::CryptDecrypt(hCryptKey, NULL, TRUE, 0, pData, &dwDataLength);
        if (FALSE == bRet)
        {
            MessageBox(_T("CryptDecrypt Error\r\n"));
            break;
        }
    } while (FALSE);

    // 關閉釋放 
    if (hCryptKey)
    {
        CryptDestroyKey(hCryptKey);
    }
    if (hCryptHash)
    {
        CryptDestroyHash(hCryptHash);
    }
    if (hCryptProv)
    {

        CryptReleaseContext(hCryptProv, 0);
    }
    return bRet;
}

// 生成公鑰和私鑰
BOOL CEncryptionDlg::GenerateKey(BYTE **ppPublicKey, DWORD *pdwPublicKeyLength, BYTE **ppPrivateKey, DWORD *pdwPrivateKeyLength)
{
    // 變量
    BOOL bRet = TRUE;
    HCRYPTPROV hCryptProv = NULL;
    HCRYPTKEY hCryptKey = NULL;
    DWORD dwPublicKeyLength = 0;
    BYTE* pPublicKey = NULL;
    DWORD dwPrivateKeyLength = 0;
    BYTE* pPrivateKey = NULL;

    do
    {
        // 擷取CSP句柄
        bRet = ::CryptAcquireContext(&hCryptProv, NULL, NULL, PROV_RSA_FULL, 0);
        if (FALSE == bRet)
        {
            MessageBox(_T("CryptAcquireContext Error\r\n"));
            break;
        }

        // 生成公/私密鑰對
        bRet = ::CryptGenKey(hCryptProv, AT_KEYEXCHANGE, CRYPT_EXPORTABLE, &hCryptKey);
        if (FALSE == bRet)
        {
            MessageBox(_T("CryptGenKey Error\r\n"));
            break;
        }

        // 擷取公鑰密鑰的長度和内容
        bRet = ::CryptExportKey(hCryptKey, NULL, PUBLICKEYBLOB, 0, NULL, &dwPublicKeyLength);
        if (FALSE == bRet)
        {
            MessageBox(_T("CryptExportKey Error\r\n"));
            break;
        }
        pPublicKey = new BYTE[dwPublicKeyLength]{0};
        bRet = ::CryptExportKey(hCryptKey, NULL, PUBLICKEYBLOB, 0, pPublicKey, &dwPublicKeyLength);
        if (FALSE == bRet)
        {
            MessageBox(_T("CryptExportKey Error\r\n"));
            break;
        }

        // 擷取私鑰密鑰的長度和内容
        bRet = ::CryptExportKey(hCryptKey, NULL, PRIVATEKEYBLOB, 0, NULL, &dwPrivateKeyLength);
        if (FALSE == bRet)
        {
            MessageBox(_T("CryptExportKey Error\r\n"));
            break;
        }
        pPrivateKey = new BYTE[dwPrivateKeyLength]{0};
        bRet = ::CryptExportKey(hCryptKey, NULL, PRIVATEKEYBLOB, 0, pPrivateKey, &dwPrivateKeyLength);
        if (FALSE == bRet)
        {
            MessageBox(_T("CryptExportKey Error\r\n"));
            break;
        }

        // 傳回資料
        *ppPublicKey = pPublicKey;
        *pdwPublicKeyLength = dwPublicKeyLength;
        *ppPrivateKey = pPrivateKey;
        *pdwPrivateKeyLength = dwPrivateKeyLength;

    } while (FALSE);

    // 釋放關閉
    if (hCryptKey)
    {
        CryptDestroyKey(hCryptKey);
    }
    if (hCryptProv)
    {
        CryptReleaseContext(hCryptProv, 0);
    }
    return bRet;
}

// 公鑰加密資料
BOOL CEncryptionDlg::RsaEncrypt(BYTE *pPublicKey, DWORD dwPublicKeyLength, BYTE *pData, DWORD &dwDataLength, DWORD dwBufferLength)
{
    // 變量
    BOOL bRet = TRUE;
    HCRYPTPROV hCryptProv = NULL;
    HCRYPTKEY hCryptKey = NULL;

    do
    {
        // 擷取CSP句柄
        bRet = ::CryptAcquireContext(&hCryptProv, NULL, NULL, PROV_RSA_FULL, 0);
        if (FALSE == bRet)
        {
            MessageBox(_T("CryptAcquireContext Error\r\n"));
            break;
        }

        // 導入公鑰
        bRet = ::CryptImportKey(hCryptProv, pPublicKey, dwPublicKeyLength, NULL, 0, &hCryptKey);
        if (FALSE == bRet)
        {
            MessageBox(_T("CryptImportKey Error\r\n"));
            break;
        }

        // 加密資料
        bRet = ::CryptEncrypt(hCryptKey, NULL, TRUE, 0, pData, &dwDataLength, dwBufferLength);
        if (FALSE == bRet)
        {
            MessageBox(_T("CryptEncrypt Error\r\n"));
            break;
        }

    } while (FALSE);

    // 關閉句柄
    if (hCryptKey)
    {
        CryptDestroyKey(hCryptKey);
    }
    if (hCryptProv)
    {
        CryptReleaseContext(hCryptProv, 0);
    }
    return bRet;
}

// 私鑰解密資料
BOOL CEncryptionDlg::RsaDecrypt(BYTE *pPrivateKey, DWORD dwProvateKeyLength, BYTE *pData, DWORD &dwDataLength)
{
    // 變量
    BOOL bRet = TRUE;
    HCRYPTPROV hCryptProv = NULL;
    HCRYPTKEY hCryptKey = NULL;

    do
    {
        // 擷取CSP句柄
        bRet = ::CryptAcquireContext(&hCryptProv, NULL, NULL, PROV_RSA_FULL, 0);
        if (FALSE == bRet)
        {
            MessageBox(_T("CryptAcquireContext Error\r\n"));
            break;
        }

        // 導入私鑰
        bRet = ::CryptImportKey(hCryptProv, pPrivateKey, dwProvateKeyLength, NULL, 0, &hCryptKey);
        if (FALSE == bRet)
        {
            MessageBox(_T("CryptImportKey Error\r\n"));
            break;
        }

        // 解密資料
        bRet = ::CryptDecrypt(hCryptKey, NULL, TRUE, 0, pData, &dwDataLength);
        if (FALSE == bRet)
        {
            MessageBox(_T("CryptDecrypt Error\r\n"));
            break;
        }

    } while (FALSE);

    // 關閉句柄
    if (hCryptKey)
    {
        CryptDestroyKey(hCryptKey);
    }
    if (hCryptProv)
    {
        CryptReleaseContext(hCryptProv, 0);
    }

    return bRet;
}