山本ワールド
Windowsプログラミング
アルゴリズム Vitual C++ 2008/2013によるWin32/Win64 APIレベルのプログラム 基礎 Vitual C++ 2008/2013によるAPIレベルのプログラム(32/64bit) Wix3でインストーラーを作る Visual C++ 2008 Standard Editonによるフォームアプリケーションのプログラム(32/64bit) Vitual C++ 2008 Standard EditonによるAPIレベルのプログラム(32/64bit) Windows 7対応 Visual C++ 2008 ExpressによるAPIレベルのプログラム Visual C++ 2005 ExpressによるAPIレベルのプログラム Visual C++ Versiosn 5 BORLAND C++ Windowsプログラム全般 Excel VBA その他MD5ハッシュを計算(Cryptography API)
概要
MD5は任意のデータ長から128bitのほぼ一意の128bitのハッシュ値を出力する関数である。電子署名やパスワードの保存、電子メールのSMTPサーバーのCRAM-MD5認証、ファイルの改ざんチェック等に用いられている。
          本プログラムは、WindowsのCryptography APIを用い_tmain関数の変数passで定義されている文字列からMD5ハッシュを算出し16進数で出力します。
          コマンドラインで動作します。
テスト環境
コンパイラ
Visual C++ 2013 Express 32bit/64bitマルチバイト/Unicode
プラットフォームツールセット Visual Studio 2013 - Windows XP (v120_xp)
実行環境
Windows 7 Enterprise Service Pack 1 64bit(Sandy Bridge-E)MD5のアルゴリズム
          MD5のアルゴリズムについてはMD5ハッシュを計算を参照してください。
        
        プログラムソースの概要
_tmain
HASH_UINT128オブジェクトを作成します。passにMD5ハッシュを算出したい文字列を指定します。
UNICODEでコンパイルした場合は、TCHAR(WCHAR)をchar型に変換します。
md5Hashed関数により文字列からMDハッシュ値を計算しHASH_UINT128に格納します。
hexメンバー関数により16進文字列を取得し_tprintfにより標準出力にハッシュ値を出力します。
mdHashed関数
引数szPasswordで示され、引数dwLengthの長さの文字列からMD5ハッシュを計算しHASH_UINT128に結果を格納します。CryptAcquireContext APIによりCSP(CryptoGraphy Service Provider)を準備します。
CryptCreateHash APIによりMD5ハッシュ計算のインスタンスを作成します。
CryptHashData APIによりMD5ハッシュを計算します。
CryptGetHashParam APIにより計算されたMD5ハッシュ値を取得しHASH_UINT128に格納します。
HASH_UINT128
ハッシュ値の保存及びハッシュ値から16進数の文字列を取得するための共用体です。ソースコード
md5_crypt.cpp
#include <windows.h>
#include <stdio.h>
#include <wincrypt.h>
#include <tchar.h>
union HASH_UINT128{
        UINT64  u64[2];
        UINT32  u32[4];
        BYTE    u8[16];
        void hex(TCHAR* s){
                _stprintf_s(s, 33, _TEXT("%0.2x%0.2x%0.2x%0.2x%0.2x%0.2x%0.2x%0.2x%0.2x%0.2x%0.2x%0.2x%0.2x%0.2x%0.2x%0.2x"), u8[0], u8[1], u8[2], u8[3], u8[4], u8[5], u8[6], u8[7], u8[8], u8[9], u8[10], u8[11], u8[12], u8[13], u8[14], u8[15]);
        }
};
bool md5Hashed(char* szPassword, DWORD dwLength, HASH_UINT128* u128){
        HCRYPTPROV hProv = 0;
        HCRYPTHASH hHash = 0;
        if (!CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT)){
                MessageBox(0, _TEXT("CryptAcquireContext"), _TEXT("Error"), MB_OK);
                return false;
        }
        if (!CryptCreateHash(hProv, CALG_MD5, 0, 0, &hHash)){
                MessageBox(0, _TEXT("CryptCreateHash"), _TEXT("Error"), MB_OK);
                CryptReleaseContext(hProv, 0);
                return false;
        }
        if (!CryptHashData(hHash, (BYTE*)szPassword, dwLength, 0)){
                MessageBox(0, _TEXT("CryptCreateHash"), _TEXT("Error"), MB_OK);
                CryptDestroyHash(hHash);
                CryptReleaseContext(hProv, 0);
                return false;
        }
        DWORD dwRead = 16;
        if (!CryptGetHashParam(hHash, HP_HASHVAL, (BYTE*)u128, &dwRead, 0)){
                MessageBox(0, _TEXT("CryptGetHashParam"), _TEXT("Error"), MB_OK);
                CryptDestroyHash(hHash);
                CryptReleaseContext(hProv, 0);
                return false;
        }
        CryptDestroyHash(hHash);
        CryptReleaseContext(hProv, 0);
        return true;
}
void _tmain(void){
        HASH_UINT128 hash;
        TCHAR* pass = _TEXT("abc");
        TCHAR hexs[34];
#ifdef UNICODE
        char sjis[256];
        WideCharToMultiByte(932, 0, pass, -1, sjis, sizeof(sjis), NULL, NULL);
        md5Hashed(sjis, (int)strlen(sjis), &hash);
#else
        md5Hashed(pass, (int)_tcslen(pass), &hash);
#endif
        hash.hex(hexs);
        _tprintf(_TEXT("%s\nmd5 %s\n"), pass,hexs);
}
        Copyright (C) 2012 山本ワールド All Rights Reserved.
      
      
    