Trusted Design

OpenSSLでダイジェスト処理

概要

OpenSSLが提供しているC言語のAPIを使ってメッセージのダイジェスト処理を実行します。OpenSSLのAPIは抽象化されているので,アルゴリズムの指定を変更することで,いろいろなダイジェスト処理を実行することができます。

利用するAPI

ダイジェスト処理を実行するためのAPIを使います。

  • EVP_get_digestbyname()
    ダイジェストで利用するアルゴリズムを取得します。
  • EVP_DigestInit_ex()
    ダイジェスト処理を初期化します。
  • EVP_DigestUpdate()
    メッセージをバッファに追加します。
  • EVP_DigestFinal_ex()
    ダイジェスト処理を実行します。

基本的にこのAPIを順番にコールしていけばOKです。

サンプルプログラム

ダイジェスト処理の関数


/*
 ハッシュ処理を実行する関数
 algに指定したアルゴリズムでハッシュ処理を行う
 */
int CreateDigest(char* alg, char* msg, int msgLen, unsigned char* digest, unsigned int* digestLen)
{

    EVP_MD_CTX* mdctx;
    const EVP_MD* md;

    /* ハッシュアルゴリズムを取得する */
    md = EVP_get_digestbyname(alg);

    mdctx = EVP_MD_CTX_new();
    /* ダイジェスト処理を実行 */
    EVP_DigestInit_ex(mdctx, md, NULL);

    /* 複数のメッセージを連結してダイジェスト処理を行う場合は
     * EVP_DigestUpdateを複数回コールする
     */
    if (!EVP_DigestUpdate(mdctx, msg, msgLen))
    {
        /* Error */
        printf("Error: %s\n", ERR_reason_error_string(ERR_get_error()));

        EVP_MD_CTX_free(mdctx);
        return 0;
    }
    if(!EVP_DigestFinal_ex(mdctx, digest, digestLen))
    {
        /* Error */
        printf("Error: %s\n", ERR_reason_error_string(ERR_get_error()));

        EVP_MD_CTX_free(mdctx);
        return 0;
    }

    EVP_MD_CTX_free(mdctx);
    return 1;
}

呼び出し側

入力するメッセージは「Digest Test Message\nTrusted Design\n」です。SHA-256とSHA-512の2つのアルゴリズムで実行してみます。


#include "openssl/evp.h"
#include "openssl/err.h"

/* バイナリ列を表示する */
int PrintDigest(unsigned char* digest, unsigned int digestLen)
{
    printf("Digest is: 0x");
    for (int i = 0; i < digestLen; i++)
        printf("%02x ", *digest++);
    printf("\n");
    return 1;
}

int main()
{
    /* ハッシュアルゴリズム */
    const char sha256[] = "SHA256";
    const char sha512[] = "SHA512";
    /* ダイジェスト処理を行うメッセージ */
    char msg[] = "Digest Test Message\nTrusted Design\n";
    int msgLen = strlen(msg);

    unsigned char digest[256];
    unsigned int digestLen = 256;

    /* SHA-256でダイジェスト処理 */
    CreateDigest((char*)sha256, msg, msgLen, digest, &digestLen);
    PrintDigest(digest, digestLen);

    /* SHA-512でダイジェスト処理 */
    memset(digest, 0x00, sizeof(digest));
    CreateDigest((char*)sha512, msg, msgLen, digest, &digestLen);
    PrintDigest(digest, digestLen);
}

実行結果

SHA-256とSHA-512のダイジェスト列が出力されます。


Digest is: 0xb6 50 f1 42 b7 7d 4e f3 dd ba 68 3f 9a 86 98 da 72 d7 8b 1f 85 0c 5b ca 6f 5d c3 a9 1c 64 7f 9a
Digest is: 0xc9 0e 50 b0 70 4d 31 a2 a6 f2 ae f4 d3 8e 2a 43 34 a0 d3 dc 27 47 19 0e f9 01 85 67 4b 46 70 e1 52 7d 22 f1 d5 f0 01 f7 26 21 97 2b 4e 29 f9 21 54 75 9d 97 90 95 12 d1 6b 78 4e 30 00 47 24 53