sha1函数给出了奇怪的输出

时间:2013-12-13 15:36:58

标签: c++ visual-studio md5 sha1

我在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>«’

为什么?

我该如何解决这个问题?

2 个答案:

答案 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<<以在结构中打印缓冲区。