[Windows] C/C++でMD5を生成する

ある処理の中でWindows上でC/C++でMD5ハッシュを計算する必要があるのがわかった。
古くからあるハッシュなのでツールはあるだろうとMSDNをみるとCryptdll.dllをLoadLibraryしなければならない、という面倒な文書があってかなりびびった。
たとえば、以下の関数。(リンク先はMicrosoftによって削除)
MD5Init Function
http://msdn.microsoft.com/en-us/library/bb432358(VS.85).aspx
ダイナミックローディングはロードできるかどうかLoadLibraryするまでわからない。
使っていてエラーが出たときにライブラリを追加するなどの修復はユーザには無理だろう。
もっと簡単な方法を探したところ、Advapi32.dllを使うとhashを作る関数が使えることがわかった。インストーラーの中のカスタムアクションで使うので可能ならばC#などマネージドよりもアンマネージドにしたい、という事情もあった。
MSDNのライブラリにはAdvapi32.dllをリンクしていろいろなハッシュ計算を行うソースコードがすでに準備されていて、MD5についても以下の例が掲載されている。
Example C Program: Creating an MD5 Hash from File Content
http://msdn.microsoft.com/en-us/library/aa382380(VS.85).aspx
FreeBSDでmd5コマンドを実行して
$ md5 -s 1234567890AB12345
MD5 (“1234567890AB12345”) = aa3b1652bfec4f78999c97f416ad7902
この結果とプログラムの結果を照合してテスト。
FreeBSDの実装にバグがあったらテストの意味がないので、このテスト方法はちょっとずるなのだけど。
実際、ハッシュライブラリのテストってどうやるのだろう。
MD5の生成についてウェブで検索すると「WindowsでC/C++を使っている場合は面倒だよ」という記事が多い。C/C++でも関数を手順通り呼べば出来るのだった。
例にあるソースコードの前半部分

 #include
 .......
 // Get handle to the crypto provider
 if (!CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT))
 {
     dwStatus = GetLastError();
     printf("CryptAcquireContext failed: %d\n", dwStatus);
     return dwStatus;
 }
 if (!CryptCreateHash(hProv, CALG_MD5, 0, 0, &hHash))
 {
     dwStatus = GetLastError();
     printf("CryptAcquireContext failed: %d\n", dwStatus);
     CryptReleaseContext(hProv, 0);
     return dwStatus;
 }
 

の2つの手順を先に済ませておけば、あとは、CryptHashDataでハッシュを計算し、CryptGetHashParamで結果を取り出せる。

広告
%d人のブロガーが「いいね」をつけました。