C++ builder XE4 > 文字列のHash値を求める > MD5 | SHA-1 | SHA-2 使用 > SHA-2はnativelyにimplementedされてない? > 対処 > IdSSLOpenSSLHeaders とLoad() | IdSSLOpenSSL とLoadOpenSSLLibrary()

```txt:動作環境
C++ Builder XE4
Indy 10.6.0.4975
```

### 前回の実装

- [c++ builder XE4 > 文字列のHash値を求める > MD5使用](https://qiita.com/7of9/items/840d1bf4515335b52109)

### 内容

- XE4での実装
- SHA-1とSHA-2のHash値を求める処理を追加

### 実装 v0.1

```Unit1.h
//---------------------------------------------------------------------------

#ifndef Unit1H
#define Unit1H
//---------------------------------------------------------------------------
#include <System.Classes.hpp>
#include <Vcl.Controls.hpp>
#include <Vcl.StdCtrls.hpp>
#include <Vcl.Forms.hpp>
//---------------------------------------------------------------------------
class TForm1 : public TForm
{
__published:	// IDE で管理されるコンポーネント
	TButton *Button1;
	TMemo *Memo1;
	void __fastcall Button1Click(TObject *Sender);
private:	// ユーザー宣言
public:		// ユーザー宣言
	__fastcall TForm1(TComponent* Owner);
};
//---------------------------------------------------------------------------
extern PACKAGE TForm1 *Form1;
//---------------------------------------------------------------------------
#endif
```

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

### 実行

![2018-11-14_11h37_38.png](https://qiita-image-store.s3.amazonaws.com/0/32870/bee8d830-210b-c7c0-ece1-e35be690696d.png)

- SHA-512がNULLの結果となる
    - SHA-224, 256, 384も同様

以下が関係するのかもしれない。

https://stackoverflow.com/questions/47379509/tidhashsha512-isavailable-is-false-on-windows-10

> answered Nov 20 '17 at 1:12
> Remy Lebeau
> Only SHA-1 (amongst a few other non-SHA hashes) is currently implemented natively.

2つのDLLを追加すればいい、とのこと。

- libeay32.dll
- ssleay32.dll

実際に2つのファイルを.exeファイルと同じフォルダに置いたがSHA-512の結果はNULLのままだった。
LoadLibrary()で2つのファイルを読込んでみたが、SHA-512の結果はNULLのままだった。

### 関連

- [C++ Builder 10.2 Tokyo > Indy > OpenSSL > Error: Could not load SSL library > libeay32.dllとssleay32.dllが関連](https://qiita.com/7of9/items/ac616e9bc593c270b5f2)
- [c++ builder / pop before smtp > SSL library not found > ssleay32.dll / libeay32.dll が必要](https://qiita.com/7of9/items/87e996dfa17c986b900a)

## 実装 v0.2

StackOverflowの質問に対して対処方法を教えていただいた。
(I was given the knowledge about how to avoid the problem. I appreciate it, Remy Lebeau).


- [SHA-512 returns NULL even using 2 DLLs (ssleay32.dll and libeay32.dll)](https://stackoverflow.com/questions/22050325/indy-10-idsmtp-connect-raising-could-not-load-ssl-library)

2つの方法がある。

### A. IdSSLOpenSSLHeaders とLoad()

```Unit1.cpp
//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop

#include <IdHashSHA.hpp> // SHA-1, SHA-2
#include <IdHashMessageDigest.hpp> // for MD5
#include <IdSSLOpenSSLHeaders.hpp>
//#include <IdSSLOpenSSL.hpp>
#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
	: TForm(Owner)
{
	Memo1->Lines->Clear();

	Load(); // IdSSLOpenSSLHeaders.hppインクルード時
	//LoadOpenSSLLibrary(); // IdSSLOpenSSL.hpp インクルード時
}
//---------------------------------------------------------------------------
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;
}
//---------------------------------------------------------------------------
```

### B. IdSSLOpenSSL とLoadOpenSSLLibrary()

```Unit1.cpp
//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop

#include <IdHashSHA.hpp> // SHA-1, SHA-2
#include <IdHashMessageDigest.hpp> // for MD5
//#include <IdSSLOpenSSLHeaders.hpp>
#include <IdSSLOpenSSL.hpp>
#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
	: TForm(Owner)
{
	Memo1->Lines->Clear();

	//Load(); // IdSSLOpenSSLHeaders.hppインクルード時
	LoadOpenSSLLibrary(); // IdSSLOpenSSL.hpp インクルード時
}
//---------------------------------------------------------------------------
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;
}
//---------------------------------------------------------------------------

```

### 実行

- libeay32.dllは.exeと同じフォルダに置いていない
- ssleay32.dllは.exeと同じフォルダに置いていない

![2018-11-14_13h14_16.png](https://qiita-image-store.s3.amazonaws.com/0/32870/cca144c9-dd64-0e32-b028-d49cfeba823c.png)