c++builderindysha2

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


My Environment:

I was studying to use MD5, SHA-1, and SHA-2s.

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;
}
//---------------------------------------------------------------------------

The result is as follows.

enter image description here

Then, I found the following:

TidHashSHA512.isavailable is false on Windows 10

According to the suggestion, I add two files to where the .exe file exists:

Still, the SHA-512 returns NULL.

What I am missing?


Solution

  • 10.6.0.4975 is a VERY old version of Indy 10. The current version is 10.6.2.5485. You need to upgrade.

    In any case, Indy 10 has native implementations of MD5 and SHA-1, those do not rely on any external hashing library at all. But SHA-512 does. Yet, you are not telling Indy which hashing library to use, such as OpenSSL. You are not instructing Indy to load the OpenSSL DLLs so it can initialize itself to use OpenSSL's SHA-512 functionality. As such, sha512->IsAvailable returns false, and sha512->HashStringAsHex() returns a blank string 1.

    This is clearly stated in the 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.

    In this case, since you are using C++ instead of Pascal, you need to add the corresponding #include statement to your code instead, either #include <IdSSLOpenSSLHeaders.hpp> or #include <IdSSLOpenSSL.hpp>, and then you can call the relevant Load function, such as in your Form's constructor.

    1: BTW, you should be using IndyTextEncoding_ASCII() instead of IndyTextEncoding(TEncoding::ASCII).