我在Visual Studio中开发了这个C ++程序,它应该打印出给定字符串的SHA1和MD5哈希值:
#include "stdafx.h"
#include <iostream>
#include <ctime>
#include "windows.h"
#include "conio.h"
#include "wincrypt.h"
char Buf [256];
DWORD BufSize;
LPSTR CreateHash(LPSTR tohash, ALG_ID alg)
{
HCRYPTPROV hProv;
HCRYPTHASH hash;
if (CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_FULL,
CRYPT_VERIFYCONTEXT))
{
if (CryptCreateHash(hProv, alg, 0, 0, &hash))
{
if (CryptHashData(hash, (BYTE *)&tohash, sizeof(tohash), 0))
{
ZeroMemory(&Buf, sizeof(Buf));
BufSize = sizeof(Buf);
if (!CryptGetHashParam(hash, HP_HASHVAL,
(BYTE *) &Buf, &BufSize, 0))
printf("Call to CryptGetHashParam failed. Error: %d\n",
GetLastError());
} else printf("Call to CryptHashData failed. Error: %d\n",
GetLastError());
if (!CryptDestroyHash(hash))
printf("Call to CryptDestroyHash failed. Error: %d\n",
GetLastError());
} else printf("Call to CryptCreateHash failed. Error: %d\n",
GetLastError());
if (!CryptReleaseContext(hProv, 0))
printf("Call to CryptReleaseContext failed. Error: %d\n",
GetLastError());
} else printf("Call to CryptAcquireContext failed. Error: %d\n",
GetLastError());
return Buf;
}
using namespace std;
int _tmain(int argc, _TCHAR* argv[])
{
cout << "SHA hash: " << CreateHash("Visual C++", CALG_SHA)<<endl;
cout << "MD5 hash: " << CreateHash("Visual C++", CALG_MD5)<<endl;
system("pause");
}
它编译但是当我运行它时,它会显示奇怪的输出。
输出应为
SHA hash: 0e4abc18f9fb9d8d6d39f047dc20fbebd4a975bd
MD5 hash: f3be2f04531a477a4bb755f9f42c6f2e
但它打印
SHA hash: ü©á*ÀªvÍŒe²5Ê¥Å?•Â
MD5 hash: òù%•þîOú°b>«’
为什么?
我该如何解决这个问题?
答案 0 :(得分:1)
加密函数将输出以原始字节存储。您期望输出为Base64或十六进制编码。要实现这一目标,您需要调用将原始二进制数据转换为所需编码字符串的函数。您可以看到如何执行此操作的示例here。
(复制示例)
CString BinaryToBase64(__in const BYTE * pbBinary, __in DWORD cbBinary)
{
// Check input pointer
ATLASSERT(pbBinary != NULL);
if (pbBinary == NULL)
AtlThrow(E_POINTER);
// Check input size
ATLASSERT(cbBinary != 0);
if (cbBinary == 0)
AtlThrow(E_INVALIDARG);
// Request size of Base64 string
DWORD cchBase64;
if (!CryptBinaryToString(pbBinary, cbBinary, CRYPT_STRING_BASE64, NULL, &cchBase64))
{
AtlThrowLastWin32();
}
// Allocate a string with required size
CString strBase64;
LPTSTR pszBase64 = strBase64.GetBuffer(cchBase64);
ATLASSERT(pszBase64 != NULL);
// Convert binary data to Base64
if (!CryptBinaryToString(pbBinary, cbBinary, CRYPT_STRING_BASE64, pszBase64, &cchBase64))
{
AtlThrowLastWin32();
}
// Release CString buffer
strBase64.ReleaseBuffer();
// Return the converted string
return strBase64;
}
您要拨打的功能是CryptBinaryToString。
答案 1 :(得分:0)
我使用以下方法逐字节打印出结果:
cout << hex << (unsigned int) result[i];
如果必须直接从函数中打印返回值,则创建包含结果缓冲区的结构并重载operator<<
以在结构中打印缓冲区。