首页 > Windows SDK > 使用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的测试代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
// 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


觉得文章还不错?点击此处对作者进行打赏!


本文地址: 程序人生 >> 使用Windows CryptoAPI计算MD5
作者:代码疯子(Wins0n) 本站内容如无声明均属原创,转载请保留作者信息与原文链接,谢谢!


更多



  1. 本文目前尚无任何评论.
  1. 本文目前尚无任何 trackbacks 和 pingbacks.