はじめに
Visual C++ 2005の環境でCryptoAPIを使ってSHA-256のハッシュ値を生成するプログラムを書いてみました。
新版暗号技術入門 秘密の国のアリス
posted with amazlet at 14.07.10
結城 浩
ソフトバンククリエイティブ
売り上げランキング: 5,620
ソフトバンククリエイティブ
売り上げランキング: 5,620
SHA-256のハッシュ値を生成する
CryptoAPIを使ってSHA-256のハッシュ値を生成するには、以下の処理が必要になります。
1.CryptAcquireContextでハンドルを取得
2.CryptCreateHashでアルゴリズムを指定する
3.CryptHashDataでハッシュ対象データを登録
4.CryptGetHashParamでハッシュ値を取り出す
ポイント
SHA-256のアルゴリズムを利用するには、CryptAcquireContextのプロパイダタイプに"PROV_RSA_AES"を指定します。
続いて、CryptCreateHash APIに"CALG_SHA_256"を指定します。
サンプルプログラム
以下のサンプルプログラムでは、"hoge"という文字列から32byteのハッシュ値を生成して、コンソールに出力しています。
サンプルプログラムを動かして得られた値は、以下のようになりましたが、SHA-256 hash calculator. Online SHA-256 hash generator. Mining Bitcoin で得られた結果と同じだったため、うまく動いていると思います。
ハッシュ値::ec b6 66 d7 78 72 5e c9 73 07 04 4d 64 2b f4 d1 60 aa bb 76 f5 6c 00
69 c7 1e a2 5b 1e 92 68 25
#include "stdafx.h" #include <windows.h> void freeResources(); HCRYPTPROV hProv = NULL; HCRYPTHASH hHash = NULL; PBYTE pbHash = NULL; int _tmain(int argc, _TCHAR *argv[]) { //-------------------------------------------------------------------------- // ハンドルの取得 //-------------------------------------------------------------------------- if (!CryptAcquireContext( &hProv, // CSPのハンドル NULL, // キーコンテナ名 NULL, // CSP名 PROV_RSA_AES, // プロパイダタイプ CRYPT_VERIFYCONTEXT)) // 特定の鍵コンテナをオープンせずにCSPのハンドルを取得する { printf(" Error in AcquireContext 0x%08x \n", GetLastError()); freeResources(); return 0; } //-------------------------------------------------------------------------- // ハッシュ値の生成 //-------------------------------------------------------------------------- if (!CryptCreateHash( hProv, // CSPのハンドル CALG_SHA_256, // ハッシュアルゴリズム 0, // ハッシュキー 0, // リザーブ &hHash)) // ハッシュオブジェクトのアドレス { printf("Error in CryptCreateHash 0x%08x \n", GetLastError()); freeResources(); return 0; } BYTE Buf[] = "hoge"; // このデータをハッシュ化する //-------------------------------------------------------------------------- // ハッシュ対象データの追加 //-------------------------------------------------------------------------- if (!CryptHashData( hHash, // CSPのハンドル Buf, // ハッシュ対象データ sizeof(Buf) - 1, // ハッシュ対象データサイズ 0)) // フラグ { printf("Error in CryptHashData 0x%08x \n", GetLastError()); freeResources(); return 0; } DWORD dwDataLen = 32; // SHA-256の場合、256bit=32byte // ハッシュ値格納用のバッファをアロケート pbHash = (BYTE *)malloc(dwDataLen); if (NULL == pbHash) { printf("unable to allocate memory\n"); freeResources(); return 0; } //-------------------------------------------------------------------------- // ハッシュ値の取り出し //-------------------------------------------------------------------------- if (!CryptGetHashParam( hHash, // CSPのハンドル HP_HASHVAL, // ハッシュ値を取得する pbHash, // ハッシュ値 &dwDataLen, // ハッシュ値のbyte数 0)) { printf("Error in CryptGetHashParam 0x%08x \n", GetLastError()); freeResources(); return 0; } // ハッシュ値をコンソールに出力する printf("ハッシュ値::"); for (DWORD i = 0 ; i < dwDataLen ; i++) { printf("%2.2x ", pbHash[i]); } printf("\n"); return 0; } // 解放処理 void freeResources() { if (hHash) { CryptDestroyHash(hHash); } if (hProv) { CryptReleaseContext(hProv, 0); } if (pbHash) { free(pbHash); } return; }
参考になったサイト
この記事を書くにあたり、以下の記事を参考にしました。