【问题标题】:md5 for an exe does not give the expected digestexe 的 md5 没有给出预期的摘要
【发布时间】:2015-03-15 22:58:27
【问题描述】:

我是新来的,我希望我做得对。

我制作了一个 C++ 应用程序,它计算以下文件的 MD5 哈希摘要 微软在此链接中的实现http://msdn.microsoft.com/en-us/library/windows/desktop/aa382380%28v=vs.85%29.aspx 情况是,当将 md5 哈希摘要与任何计算 md5 摘要的现成工具进行比较时,任何类型的文件都是正确的。除非手中的文件是像 cmd.exe 这样的可执行文件。哈希摘要是不同的,取决于 exe 的位置。如果您将 cmd.exe 移动到另一个位置,那么摘要将再次变得不同。所以我继续使用 openssl 库实现相同的功能来面对同样的问题。我注意到来自微软实现和 openssl 的哈希摘要是相同的。所以我认为在传递文件以计算摘要之前读取文件时缺少一些东西。但我搜索了很多,一无所获。 我尝试使用 win API 中的“createfile”和“fopen”读取文件以给出相同的结果......所以请帮我解决这个问题,我错过了什么?

这里是源代码

#include "stdafx.h"
#include <stdio.h>
#include <windows.h>
#include <Wincrypt.h>

#define BUFSIZE 1024
#define MD5LEN  16

int _tmain(int argc, _TCHAR* argv[])
{
    DWORD dwStatus = 0;
    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 rgbDigits[] = "0123456789abcdef";
    LPCWSTR filename=L"C:\\Windows\\System32\\cmd.exe";
    // Logic to check usage goes here.

    hFile = CreateFile(filename,
        GENERIC_READ,
        FILE_SHARE_READ,
        NULL,
        OPEN_EXISTING,
        FILE_FLAG_SEQUENTIAL_SCAN,
        NULL);

    if (INVALID_HANDLE_VALUE == hFile)
    {
        dwStatus = GetLastError();
        printf("Error opening file %s\nError: %d\n", filename, 
            dwStatus); 
        return dwStatus;
    }

    // Get handle to the crypto provider
    if (!CryptAcquireContext(&hProv,
        NULL,
        NULL,
        PROV_RSA_FULL,
        CRYPT_VERIFYCONTEXT))
    {
        dwStatus = GetLastError();
        printf("CryptAcquireContext failed: %d\n", dwStatus); 
        CloseHandle(hFile);
        return dwStatus;
    }

    if (!CryptCreateHash(hProv, CALG_MD5, 0, 0, &hHash))
    {
        dwStatus = GetLastError();
        printf("CryptAcquireContext failed: %d\n", dwStatus); 
        CloseHandle(hFile);
        CryptReleaseContext(hProv, 0);
        return dwStatus;
    }

    while (bResult = ReadFile(hFile, rgbFile, BUFSIZE, 
        &cbRead, NULL))
    {
        if (0 == cbRead)
        {
            break;
        }

        if (!CryptHashData(hHash, rgbFile, cbRead, 0))
        {
            dwStatus = GetLastError();
            printf("CryptHashData failed: %d\n", dwStatus); 
            CryptReleaseContext(hProv, 0);
            CryptDestroyHash(hHash);
            CloseHandle(hFile);
            return dwStatus;
        }
    }

    if (!bResult)
    {
        dwStatus = GetLastError();
        printf("ReadFile failed: %d\n", dwStatus); 
        CryptReleaseContext(hProv, 0);
        CryptDestroyHash(hHash);
        CloseHandle(hFile);
        return dwStatus;
    }

    cbHash = MD5LEN;
    if (CryptGetHashParam(hHash, HP_HASHVAL, rgbHash, &cbHash, 0))
    {
        printf("MD5 hash of file %s is: ", filename);
        for (DWORD i = 0; i < cbHash; i++)
        {
            printf("%c%c", rgbDigits[rgbHash[i] >> 4],
                rgbDigits[rgbHash[i] & 0xf]);
        }
        printf("\n");
    }
    else
    {
        dwStatus = GetLastError();
        printf("CryptGetHashParam failed: %d\n", dwStatus); 
    }

    CryptDestroyHash(hHash);
    CryptReleaseContext(hProv, 0);
    CloseHandle(hFile);

    return dwStatus; 


    return 0;
}

此代码计算哈希“59a1d4facd7b333f76c4142cd42d3aba” 另一方面,“数字火山哈希工具”和“md5 和 sha 校验和实用程序 v2.1”计算哈希“fc0b4a626881d7c5980d757214db2d25”

【问题讨论】:

  • 我们不知道您缺少什么——我们不知道您拥有什么。请阅读stackoverflow.com/help/mcve
  • 文件的 md5 哈希值应该与路径无关,如果 md5 代码没有问题。
  • 我已经添加了源代码
  • 任何更新,提前致谢
  • 根据我的阅读,源代码对我来说是正确的,不幸的是我没有 Windows 机器来测试它。

标签: c++ md5 wincrypt


【解决方案1】:

您的代码是正确的!您遇到了 Windows 的特殊性。

您正在阅读的文件位于C:\Windows\System32 目录中。

在 64 位 Windows 上,如果 32 位应用程序尝试访问该目录 it gets redirectedC:\Windows\SysWow64

由于C:\Windows\System32C:\Windows\SysWow64 中都有cmd.exe 文件,但它们是不同的构建和不同的哈希值,因此检查C:\Windows\System32\cmd.exe 哈希值的程序将根据它们是否为 32 给出不同的结果-bit 或 64 位。

您可以通过构建 32 位和 64 位的示例程序并观察它们给出不同的答案来亲自了解这一点。

【讨论】:

    猜你喜欢
    • 2023-04-02
    • 2018-09-18
    • 2019-09-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-01-08
    相关资源
    最近更新 更多