SHA-512 returns NULL 即使使用 2 个 DLL(ssleay32.dll 和 libeay32.dll)

SHA-512 returns NULL even using 2 DLLs (ssleay32.dll and libeay32.dll)

我的环境:

我正在学习使用 MD5、SHA-1 和 SHA-2。

Unit1.cpp

//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop

#include <IdHashSHA.hpp> // SHA-1, SHA-2
#include <IdHashMessageDigest.hpp> // for MD5
#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
    : TForm(Owner)
{
    Memo1->Lines->Clear();
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
    String msg;
    msg = L"Hello, world";
    String hash;

    // 1. MD5
    TIdHashMessageDigest5 *md5;
    md5 = new TIdHashMessageDigest5();
    //
    hash = md5->HashStringAsHex(msg, IndyTextEncoding(TEncoding::ASCII)).LowerCase();
    Memo1->Lines->Add(L"MD5: " + hash);
    delete md5;

    // 2. SHA-1
    TIdHashSHA1 *sha1;
    sha1 = new TIdHashSHA1();
    //
    hash = sha1->HashStringAsHex(msg, IndyTextEncoding(TEncoding::ASCII)).LowerCase();
    Memo1->Lines->Add(L"SHA-1:" + hash);
    delete sha1;

    // 3. SHA-2 (SHA-512)
    TIdHashSHA512 *sha512;
    sha512 = new TIdHashSHA512();
    //
    hash = sha512->HashStringAsHex(msg, IndyTextEncoding(TEncoding::ASCII)).LowerCase();
    Memo1->Lines->Add(L"SHA-512:" + hash);
    delete sha512;
}
//---------------------------------------------------------------------------

结果如下

然后,我发现了以下内容:

TidHashSHA512.isavailable is false on Windows 10

根据建议,我在.exe文件所在的位置添加了两个文件:

不过,SHA-512 returns NULL。

我错过了什么?

10.6.0.4975 是 Indy 10 的一个非常旧的版本。当前版本是 10.6.2.5485。您需要升级。

无论如何,Indy 10 具有 MD5 和 SHA-1 的本机实现,它们根本不依赖任何外部哈希库。但是 SHA-512 可以。然而,您并没有告诉 Indy 使用哪个散列库,例如 OpenSSL。您没有指示 Indy 加载 OpenSSL DLL,因此它可以初始化自身以使用 OpenSSL 的 SHA-512 功能。因此,sha512->IsAvailable returns 为假,sha512->HashStringAsHex() returns 为空字符串 1.

这在accepted answer to the question you linked to中有明确说明:

Indy provides an implementation that uses hashing functions from OpenSSL. To use it, you can either:

  • add the IdSSLOpenSSLHeaders unit to your uses clause, and then call its Load() function at runtime.

  • add the IdSSLOpenSSL unit to your uses clause, and then call its LoadOpenSSLLibrary() function at runtime.

在这种情况下,由于您使用的是 C++ 而不是 Pascal,因此您需要将相应的 #include 语句添加到您的代码中,#include <IdSSLOpenSSLHeaders.hpp>#include <IdSSLOpenSSL.hpp>,然后您可以调用相关的 Load 函数,例如在您的 Form 的构造函数中。

1:顺便说一句,您应该使用 IndyTextEncoding_ASCII() 而不是 IndyTextEncoding(TEncoding::ASCII)