OpenSSLでHMAC生成
概要
OpenSSLが提供しているC言語のAPIを使ってメッセージのHMACを生成します。HMACは共通鍵とハッシュアルゴリズムを利用してメッセージのダイジェストを生成します。
メッセージを受け取った人は,あらかじめ共有してある共通鍵を利用してHMACを生成し,受け取ったHMACと比較することでメッセージが改ざんされていないことを確認することができます。
利用するAPI
HMAC生成を実行するためのAPI
- EVP_get_digestbyname()
ハッシュアルゴリズムを取得します。 - HMAC_Init_ex()
HMAC処理を初期化します。 - HMAC_Update()
メッセージをバッファに追加します。 - HMAC_Final()
HMAC処理を実行し,結果を受け取ります。 - HMAC_CTX_free()
HMAC処理を終了します。
基本的にこのAPIを順番にコールしていけばOKです。
サンプルプログラム
HMACを計算する関数
/*
HMACを計算する関数
*/
int Calc_HMAC(unsigned char* inbuf, int inbufLen, unsigned char* outbuf, unsigned int* outbufLen)
{
HMAC_CTX* ctx;
const EVP_MD* md;
char alg[] = "SHA256";
md = EVP_get_digestbyname(alg);
/*
* 鍵とIVはダミー
* 通常はセキュアな領域から取得するので,関数の外部から与えられても良い
*/
unsigned char key[] = "ABCDEFGHIJKLMNOP";
/* HMACを初期化する */
ctx = HMAC_CTX_new();
/* 鍵とダイジェストアルゴリズムを設定する */
HMAC_Init_ex(ctx, key, sizeof(key), md, NULL);
/* HMACを生成する */
if (!HMAC_Update(ctx, inbuf, inbufLen)) {
// Error
printf("Error: %s\n", ERR_reason_error_string(ERR_get_error()));
HMAC_CTX_free(ctx);
return 0;
}
/* HMACを取得する */
if (!HMAC_Final(ctx, outbuf, outbufLen)) {
// Error
printf("Error: %s\n", ERR_reason_error_string(ERR_get_error()));
HMAC_CTX_free(ctx);
return 0;
}
HMAC_CTX_free(ctx);
return 1;
}
呼び出し側
入力するメッセージは「HMAC Test Message\nTrusted Design\n」です。
#include "openssl/evp.h"
#include "openssl/err.h"
#include "openssl/hmac.h"
/*
バイト列を出力する関数
*/
int PrintBytes(unsigned char* bytes, unsigned int bytesLen)
{
printf("Data is: 0x");
for (int i = 0; i < bytesLen; i++)
printf("%02x ", *bytes++);
printf("\n");
return 1;
}
int main()
{
/* HMAC処理を行うメッセージ */
unsigned char msg[] = "HMAC Test Message\nTrusted Design\n";
int msgLen = sizeof(msg);
unsigned char hmac[256];
unsigned int hmacLen = 256;
Calc_HMAC(msg, msgLen, hmac, &hmacLen);
PrintBytes(hmac, hmacLen);
}
実行結果
SHA-256のHMACなので32Byteのバイト列が出力されます。
Data is: 0x45 66 51 87 ea 76 da 6b 0e e3 1c 3b 97 9f cd 2a 56 71 a1 8f 52 36 c0 59 a5 c7 54 4e e3 aa b6 dd