C++ でファイルの MD5 ハッシュを取得する

Zeeshan Afridi 2023年10月12日
  1. ハッシュ 関数とは
  2. MD5とは
  3. まとめ
C++ でファイルの MD5 ハッシュを取得する

MD5 は、以前は暗号化に使用されていた暗号化プロトコルですが、現在は認証に一般的に使用されています。 これは、プレーン テキストに対して暗号化されたハッシュ値を生成する hash 関数のハッシュ プロセスに基づいています。

ハッシュ 関数とは

MD5 (メッセージ ダイジェスト アルゴリズム) を調べる前に、hash 関数を理解することが重要です。 ハッシュは、平文をハッシュ値のある暗号文に変換するために使用される ハッシュ 関数プロセスです。

これは、プレーン テキストを暗号文および一般に圧縮されたハッシュ値に変換するのに役立つ数学関数に基づいています。

ハッシュ関数

この図は、hash 関数の動作を示しています。 メッセージが hash 関数への入力であるという基本的なメッセージを提供します。 いくつかのプロセスを実行し、暗号文として知られる暗号化されたランダム値として出力を提供します。

hash関数の特徴

  1. 出力は、プレーン テキストのサイズに関係なく、常に同じ長さ (128 ビット) です。
  2. 元のメッセージが 128 ビットを超える場合でも圧縮します。
  3. データ (メッセージ) をダイジェストし、データをより小さなハッシュ値表現に表します。
  4. ハッシュ値は、メッセージごとに一意である必要があります。
  5. 同じメッセージのハッシュ値は常に同じである必要があります。

MD5とは

MD5 (メッセージ ダイジェスト アルゴリズム) は、メッセージの認証、コンテンツの検証、およびデジタル署名に使用される暗号化プロトコルです。 Ronald Rivest は [1991](https://en.wikipedia.org/wiki/MD5#:~:text=Ronald Rivest in-,1991 to,-replace an earlier) に MD4 の高度なバージョンとして設計しました。 送受信されたファイルを検証するための hash 関数に基づいています。

MD5 は現在、データ認証に使用されていますが、当初はデータ暗号化に使用されていました。 認証は、認証とデータ整合性の実現に役立つ暗号化のコア プロパティの 1つです。

MD5 は、ファイルまたはパスワードのハッシュ値をビットごとにチェックするため、パスワードの信頼性またはファイルのオリジナル性の検証に効率的なアルゴリズムです。

MD5 アルゴリズムには 4つの重要なステップがあります。

  1. パディング ビット
  2. 長さを追加
  3. MB バッファの初期化
  4. 各ブロックを処理する

パディング ビット

最初のメッセージは、4000 ビット、1231 ビット、またはその他の任意のビット数の任意のサイズにすることができます。 次に、いくつかのパディング ビットを追加します。 最後に、64 ビットのサイズが 512 の倍数であることを確認する必要があります。

先頭に 1 を追加し、残りの 0 をパディングに追加します。

追加の長さ

このステップでは、最終的なメッセージを 512 の倍数にするために、さらにいくつかの文字を追加する必要があります。 そのためには、元のメッセージの長さを 64 ビットの形式で表現します。

そして、この組み合わせにより、どの読み取り値をハッシュするかという最終的なメッセージが得られます。

MB バッファの初期化

バッファ ABC、および D を初期化する時が来ました。 各バッファーは、メッセージ ダイジェストの値を計算するために使用されます。 各バッファは 32 ビットで、次のように初期化されます。

A = 01 23 45 67
B = 89 ab cd ef
C = fe dc ba 98
D = 76 54 32 10

ブロックごとに処理する

各 512 ビット ブロックは、さらに 16 ブロックの小さなチャンクに分割されます。 各サブブロックのサイズは 32 ビットです。 全体として、4 ラウンドで各ブロックが処理され、いくつかの特定の操作が実行されます。

各ラウンドは 16 個のブロックすべてを使用し、バッファーは定数配列値です。

定数配列は T[1] -> T[64] と表記され、すべてのサブブロックは M[0] -> m[15] と表記されます。

MD5の働き

この図によると、すべての単一バッファに対して値が実行されていることがわかります。

void print_MD5(unsigned char* md, long size = MD5_DIGEST_LENGTH) {
  for (int i = 0; i < size; i++) {
    cout << hex << setw(2) << setfill('0') << (int)md[i];
  }
}

この関数は、MD を正しく印刷するために使用されます。

#include <iostream>

#include "md5.h"  // This is an external library that you need to import for MD5 algorithm

using namespace std;  // for cout

int main() {
  cout << "md5 of 'grape' : " << md5("grape") << endl;
  return 0;
}

出力:

md5 of 'grape' : b781cbb29054db12f88f08c6e161c199

このコードには外部ライブラリ md5.h が含まれており、MD5 アルゴリズムを使用してプレーン テキストのハッシュ値を生成できます。 ファイルのハッシュ値を返す md5 関数に引数として文字列 grape を渡します。

fileSize = file.tellg();
cout << "File size \t" << fileSize << endl;
memBlock = new char[fileSize];
file.seekg(0, ios::beg);
file.read(memBlock, fileSize);
file.close();

ファイルサイズを取得し、メモリにコピーします。

まとめ

MD5 ハッシュ アルゴリズムは、プレーン テキストからの暗号ハッシュ値の複雑な数式に基づいています。 MD5 アルゴリズムの動作で見たように、平文を特定のサイズのブロックに変換し、それに対してさまざまな操作を実行します。

最後に、テキストに対して 128 ビット値を圧縮します。 アルファベット a の MD5 アルゴリズムのハッシュ値は、0cc175b9c0f1b6a831c399e269772661 のようになります。

著者: Zeeshan Afridi
Zeeshan Afridi avatar Zeeshan Afridi avatar

Zeeshan is a detail oriented software engineer that helps companies and individuals make their lives and easier with software solutions.

LinkedIn