|
在Windows SDK中,UNICODE 环境下VC++快速取得文件HASH MD5
在使用CryptoAPI时, `PROV_RSA_MD5` 是一个常量,表示使用MD5算法的加密服务提供者。然而,在Windows SDK中,MD5算法的加密服务提供者并不是直接通过 `PROV_RSA_MD5` 来获取的。
可以使用 `CryptAcquireContext` 函数的 `CRYPT_VERIFYCONTEXT` 参数来获取一个上下文,而不需要指定特定的提供者。然后,使用 `CryptCreateHash` 函数时,指定 `CALG_MD5` 作为哈希算法。
以下是修正后的代码示例:
- #include <windows.h>
- #include <wincrypt.h>
- #include <iostream>
- #include <string>
- #include <sstream>
- #include <iomanip>
- std::wstring GetFileMD5Hash(const std::wstring& filePath) {
- // 初始化CryptoAPI
- HCRYPTPROV hProv = 0;
- HCRYPTHASH hHash = 0;
- BYTE hash[16]; // MD5产生16字节的哈希值
- DWORD hashLen = sizeof(hash);
- // 打开文件
- HANDLE hFile = CreateFileW(filePath.c_str(), GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
- if (hFile == INVALID_HANDLE_VALUE) {
- std::wcerr << L"无法打开文件: " << filePath << std::endl;
- return L"";
- }
- // 获取加密服务提供者
- if (!CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_AES, CRYPT_VERIFYCONTEXT)) {
- CloseHandle(hFile);
- std::wcerr << L"CryptAcquireContext 失败。" << std::endl;
- return L"";
- }
- // 创建哈希对象
- if (!CryptCreateHash(hProv, CALG_MD5, 0, 0, &hHash)) {
- CryptReleaseContext(hProv, 0);
- CloseHandle(hFile);
- std::wcerr << L"CryptCreateHash 失败。" << std::endl;
- return L"";
- }
- // 读取文件并更新哈希
- const DWORD bufferSize = 4096;
- BYTE buffer[bufferSize];
- DWORD bytesRead;
- while (ReadFile(hFile, buffer, bufferSize, &bytesRead, NULL) && bytesRead > 0) {
- CryptHashData(hHash, buffer, bytesRead, 0);
- }
- // 获取哈希值
- CryptGetHashParam(hHash, HP_HASHVAL, hash, &hashLen, 0);
- // 关闭句柄
- CryptDestroyHash(hHash);
- CryptReleaseContext(hProv, 0);
- CloseHandle(hFile);
- // 将哈希值转换为字符串
- std::wstringstream ss;
- for (DWORD i = 0; i < hashLen; i++) {
- ss << std::hex << std::setw(2) << std::setfill(L'0') << static_cast<int>(hash[i]);
- }
- return ss.str();
- }
- int main() {
- std::wstring filePath = L"your_file_path_here"; // 替换为你的文件路径
- std::wstring md5Hash = GetFileMD5Hash(filePath);
- if (!md5Hash.empty()) {
- std::wcout << L"MD5 Hash: " << md5Hash << std::endl;
- }
- return 0;
- }
复制代码
### 说明:
1. **加密服务提供者**:在 `CryptAcquireContext` 中使用 `PROV_RSA_AES` ,这是一个通用的提供者,可以支持多种加密算法,包括MD5。
2. **哈希算法**:在 `CryptCreateHash` 中仍然使用 `CALG_MD5` 来指定MD5哈希算法。
确保在编译时链接 `Advapi32.lib` 库。这样修改后,代码应该可以正常工作,计算文件的MD5哈希值。
|
|