使用Windows CryptoAPI计算MD5

使用Windows CryptoAPI计算MD5

About Windows CryptoAPI: Application programming interface that enables application developers to add authentication, encoding, and encryption to Windows-based applications.

直接使用Windows提供的CryptAcquireContext、CryptCreateHash、CryptHashData、CryptGetHashParam等API就可以计算MD5了,稍微封装了一下,可以算文件或者字符串的MD5值,文件传入UNICODE类型字符串的路径,字符串使用普通的CHAR,因为UNICODE和非UNICODE算出来的MD5不一样(字符串看上去一样,实际的BYTE不一样)。
explorer.exe计算出MD5为CDE09BCDF5FDE1E2EAC52C0F93362B79

计算MD5的测试代码如下:

// Author: 代码疯子
// Blog: http://www.programlife.net/
#include <stdio.h>
#include <windows.h>
#include <Wincrypt.h>
 
#define CHECK_NULL_RET(bCondition) if (!bCondition) goto Exit0
#define BUFSIZE 1024
#define MD5LEN  16
 
BOOL GetContentMD5(
    BYTE *pszFilePath, 
    BOOL bFile, 
    BOOL bUpperCase, 
    TCHAR *pszResult,
    DWORD &dwStatus)
{
    BOOL bResult = FALSE;
    HCRYPTPROV hProv = 0;
    HCRYPTHASH hHash = 0;
    HANDLE hFile = NULL;
    BYTE rgbFile[BUFSIZE];
    DWORD cbRead = 0;
    BYTE rgbHash[MD5LEN];
    DWORD cbHash = 0;
    CHAR rgbDigitsL[] = "0123456789abcdef";
    CHAR rgbDigitsU[] = "0123456789ABCDEF";
    CHAR *rgbDigits = bUpperCase ? rgbDigitsU : rgbDigitsL;
    TCHAR szResult[MD5LEN*2+1] = {0};
 
    dwStatus = 0;
    bResult = CryptAcquireContext(&hProv,
        NULL,
        NULL,
        PROV_RSA_FULL,
        CRYPT_VERIFYCONTEXT);
    CHECK_NULL_RET(bResult);
 
    bResult = CryptCreateHash(hProv, CALG_MD5, 0, 0, &hHash);
    CHECK_NULL_RET(bResult);
 
    if (bFile)
    {
        hFile = CreateFile((TCHAR *)pszFilePath,
            GENERIC_READ,
            FILE_SHARE_READ,
            NULL,
            OPEN_EXISTING,
            FILE_FLAG_SEQUENTIAL_SCAN,
            NULL);
        CHECK_NULL_RET(!(INVALID_HANDLE_VALUE == hFile));
 
        while (bResult = ReadFile(hFile, rgbFile, BUFSIZE, 
            &cbRead, NULL))
        {
            if (0 == cbRead)
            {
                break;
            }
 
            bResult = CryptHashData(hHash, rgbFile, cbRead, 0);
            CHECK_NULL_RET(bResult);
        }
    }
    else
    {
        bResult = CryptHashData(hHash, pszFilePath, strlen((CHAR *)pszFilePath), 0);
        CHECK_NULL_RET(bResult);
    }
 
    cbHash = MD5LEN;
    if (bResult = CryptGetHashParam(hHash, HP_HASHVAL, rgbHash, &cbHash, 0))
    {
        TCHAR szTmpBuff[3] = {0};
        for (DWORD i = 0; i < cbHash; i++)
        {
            swprintf(szTmpBuff, TEXT("%c%c"), rgbDigits[rgbHash[i] >> 4],
                rgbDigits[rgbHash[i] & 0xf]);
            lstrcat(szResult, szTmpBuff);
        }
        bResult = TRUE;
    }
 
Exit0:
    dwStatus = GetLastError();
    CryptDestroyHash(hHash);
    CryptReleaseContext(hProv, 0);
    CloseHandle(hFile);
 
    lstrcpy(pszResult, szResult);
 
    return bResult; 
}
 
int main(int argc, char* argv[])
{
    DWORD dwStatus = 0;
    TCHAR szResult[MD5LEN*2+1] = {0};
    TCHAR szFilePath[] = TEXT("C:\\Windows\\System32\\notepad.exe");
    CHAR szContent[] = "explorer.exe";
 
    GetContentMD5((BYTE *)szFilePath, 
        TRUE, TRUE, szResult, dwStatus);
    MessageBox(NULL, szResult, TEXT("MD5"), MB_OK);
 
    GetContentMD5((BYTE *)szContent, FALSE, TRUE, szResult, dwStatus);
    MessageBox(NULL, szResult, TEXT("MD5"), MB_OK);
 
    return 0;
}
 
// explorer.exe的MD5为CDE09BCDF5FDE1E2EAC52C0F93362B79


参考:Example C Program: Creating an MD5 Hash from File Content

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值