【发布时间】:2012-01-02 14:35:27
【问题描述】:
我正在尝试使用 Microsoft 加密 API 来计算 MD5 哈希,但得到的哈希不正确:
#include <windows.h>
#include <stdio.h>
#include <wincrypt.h>
char* HashMD5(char* data, DWORD *result)
{
DWORD dwStatus = 0;
DWORD cbHash = 16;
int i = 0;
HCRYPTPROV cryptProv;
HCRYPTHASH cryptHash;
BYTE hash[16];
char *hex = "01234567879abcdef";
char *strHash = "00000000000000000000000000000000";
if(!CryptAcquireContext(&cryptProv, NULL, MS_DEF_PROV, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT))
{
dwStatus = GetLastError();
printf("CryptAcquireContext failed: %d\n", dwStatus);
*result = dwStatus;
return NULL;
}
if(!CryptCreateHash(cryptProv, CALG_MD5, 0, 0, &cryptHash))
{
dwStatus = GetLastError();
printf("CryptCreateHash failed: %d\n", dwStatus);
CryptReleaseContext(cryptProv, 0);
*result = dwStatus;
return NULL;
}
if(!CryptHashData(cryptHash, (BYTE*)data, strlen(data), 0))
{
dwStatus = GetLastError();
printf("CryptHashData failed: %d\n", dwStatus);
CryptReleaseContext(cryptProv, 0);
CryptDestroyHash(cryptHash);
*result = dwStatus;
return NULL;
}
if(!CryptGetHashParam(cryptHash, HP_HASHVAL, hash, &cbHash, 0))
{
dwStatus = GetLastError();
printf("CryptGetHashParam failed: %d\n", dwStatus);
CryptReleaseContext(cryptProv, 0);
CryptDestroyHash(cryptHash);
*result = dwStatus;
return NULL;
}
for(i = 0; i < cbHash; i++)
{
strHash[i*2] = hex[hash[i] >> 4];
strHash[(i*2)+1] = hex[hash[i] & 0xF];
}
CryptReleaseContext(cryptProv, 0);
CryptDestroyHash(cryptHash);
return strHash;
}
int main(int argc, char **argv)
{
DWORD result = 0;
char* hash;
if(argc != 2)
{
printf("Usage: crypto.exe <word>\n");
return 0;
}
hash = HashMD5(argv[1], &result);
if(result == 0)
{
printf("Hash of '%s' is: %s\n", argv[1], hash);
}
else
{
printf("Failed! Result: %d\n", result);
}
return result;
}
代码执行正常,没有打印错误信息,但返回的哈希值对于某些明文不正确:
$ ./crypto.exe test
Hash of 'test' is: 078e6abc4621c373b9cd4d832627a4e6
$ ./crypto.exe StackOverflow
Hash of 'StackOverflow' is: 84c7cb17766b446e5d4084d8ebd87e82
后者是正确的,但前者应该是098f6bcd4621d373cade4e832627b4f6。
我做错了什么?
【问题讨论】:
-
这是代码审查网站的工作。
-
@bmargulies:不,代码审查不适用于失败的代码。它真的属于这里。
-
根据代码审查常见问题解答,他们审查了有效但可能不是最佳的代码。他们还声明代码审查不是为了解决问题。此代码已损坏,需要进行故障排除。
-
其实两个hash都是错误的(虽然不完全),所以我怀疑是转换成hex有问题。
标签: c winapi cryptography md5 cryptoapi