ネットワーク WG
Request for Comments: 2202
分類: 情報提供
P. Cheng
IBM
R. Glenn
NIST
1997年 9月

 

HMAC-MD5 と HMAC-SHA-1 のためのテストケース
(Test Cases for HMAC-MD5 and HMAC-SHA-1)

このメモの位置付け 

このメモは、インターネット・コミュニティに対して情報提供を行うものです。いかなる種類のインターネット標準も、このメモでは指定していません。このメモの配布に制限はありません。

要旨

本書では、HMAC-MD5 と HMAC-SHA-1 それぞれに対する 2 セットのテストケースを提供します。HMAC-MD5 と HMAC-SHA-1 は、MD5 [MD5] ハッシュ関数と SHA-1 [SHA] ハッシュ関数を使用して構成された HMAC [HMAC] メッセージ認証関数です。これらは、IPSEC [OG,CG] や他のプロトコルでメッセージを認証するために使用されます。本書で提供されるテストケースとその結果は、HMAC-MD5 と HMAC-SHA-1 の実装の準拠試験に使用されることを意図しています。

1. はじめに 

ある特定のハッシュ関数を使用して HMAC メッセージ認証関数を構成する一般的な方法については、[HMAC] の 2 章に記述されています。これについては、ここで繰り返すことはしないことにします。[HMAC] の 5 章では、HMAC の出力の最後を切って省略するための規則についても議論されています。この規則では、上位ビット(ネットワークバイト順序を想定した場合、左側のビット)を残す必要があります。

2 章と 3 章では、HMAC-MD5 と HMAC-SHA-1 それぞれに対するテストケースを提供します。各ケースには、鍵、データ、そしてその結果が含まれています。鍵およびデータの値は、16進数(「0x」で始まる)またはダブルコーテーション付きの ASCII 文字のどちらかで表示されています。値が ASCII 文字である場合には、そのテストケースに対する HMAC 計算には、文字中の最後の NULL 文字(「\0」)は含まれません。

HMAC-SHA-1 の結果を生成する関数の C のソースコードを付録に収めてあります。ここで、これらの関数はシンプルで理解しやすいものを意図していることに注意してください。これらは、全く最適化されていません。HMAC-MD5 を計算する C のソースコードは、[MD5] にあります。また、付録で説明されているように、HMAC-SHA-1 を少し修正するだけで HMAC-MD5 のコードを得ることができます。

本書のテストケースは、3 つの独立した実装(NIST から 1 つと  IBM Research から 2 つ)で相互検証されています。IBM の実装の 1 つは、付録のコードとは全く異なる最適化されたコードを使用しています。本書で提供される結果と一致する実装は、他の同じような実装と相互運用できる必要があります。しかし、このような実装が [HMAC] における HMAC の定義に関して全く正確であるとは言えません。

2. HMAC-MD5 のためのテストケース 

test_case =     1
key =           0x0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b
key_len =       16
data =          "Hi There"
data_len =      8
digest =        0x9294727a3638bb1c13f48ef8158bfc9d

test_case =     2
key =           "Jefe"
key_len =       4
data =          "what do ya want for nothing?"
data_len =      28
digest =        0x750c783e6ab0b503eaa86e310a5db738

test_case =     3
key =           0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
key_len         16
data =          0xdd を 50 回繰り返す
data_len =      50
digest =        0x56be34521d144c88dbb8c733f0e8b3f6

test_case =     4
key =           0x0102030405060708090a0b0c0d0e0f10111213141516171819
key_len         25
data =          0xcd を 50 回繰り返す
data_len =      50
digest =        0x697eaf0aca3a3aea3a75164746ffaa79

test_case =     5
key =           0x0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c
key_len =       16
data =          "Test With Truncation"
data_len =      20
digest =        0x56461ef2342edc00f9bab995690efd4c
digest-96       0x56461ef2342edc00f9bab995

test_case =     6
key =           0xaa を 80 回繰り返す
key_len =       80
data =          "Test Using Larger Than Block-Size Key - Hash Key First"
data_len =      54
digest =        0x6b1ab7fe4bd7bf8f0b62e6ce61b9d0cd

test_case =     7
key =           0xaa を 80 回繰り返す
key_len =       80
data =          "Test Using Larger Than Block-Size Key and Larger Than One Block-Size Data"
data_len =      73
digest =        0x6f630fad67cda0ee1fb1f562db3aa53e

3. HMAC-SHA-1 のためのテストケース 

test_case =     1
key =           0x0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b
key_len =       20
data =          "Hi There"
data_len =      8
digest =        0xb617318655057264e28bc0b6fb378c8ef146be00

test_case =     2
key =           "Jefe"
key_len =       4
data =          "what do ya want for nothing?"
data_len =      28
digest =        0xeffcdf6ae5eb2fa2d27416d5f184df9c259a7c79

test_case =     3
key =           0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
key_len =       20
data =          0xdd を 50 回繰り返す
data_len =      50
digest =        0x125d7342b9ac11cd91a39af48aa17b4f63f175d3

test_case =     4
key =           0x0102030405060708090a0b0c0d0e0f10111213141516171819
key_len =       25
data =          0xcd を 50 回繰り返す
data_len =      50
digest =        0x4c9007f4026250c6bc8414f9bf50c86c2d7235da

test_case =     5
key =           0x0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c
key_len =       20
data =          "Test With Truncation"
data_len =      20
digest =        0x4c1a03424b55e07fe7f27be1d58bb9324a9a5a04
digest-96 =     0x4c1a03424b55e07fe7f27be1

test_case =     6
key =           0xaa を 80 回繰り返す
key_len =       80
data =          "Test Using Larger Than Block-Size Key - Hash Key First"
data_len =      54
digest =        0xaa4ae5e15272d00e95705637ce8a3b55ed402112

test_case =     7
key =           0xaa を 80 回繰り返す
key_len =       80
data =          "Test Using Larger Than Block-Size Key and Larger Than One Block-Size Data"
data_len =      73
digest =        0xe8e99d0f45237d786d6bbaa7965c7808bbff1a91

4. セキュリティについての考慮事項 

本書では、セキュリティに関する問題は引き起こされません。HMAC 構成の強度に関する議論は、[HMAC] にあります。

参考文献 

[HMAC] Krawczyk, H., Bellare, M., and R. Canetti, "HMAC: Keyed-Hashing for Message Authentication", RFC 2104, 1997年 2月.

[MD5] Rivest, R., "The MD5 Message-Digest Algorithm", RFC 1321, 1992年 4月.

[SHA] NIST, FIPS PUB 180-1: Secure Hash Standard, 1995年 4月.

[OG] Oehler, M., and R. Glenn, "HMAC-MD5 IP Authentication with Replay Prevention", RFC 2085, 1997年 2月.

[CG] Chang, S., and R. Glenn, "HMAC-SHA IP Authentication with Replay Prevention", Work in Progress.

著者のアドレス

Pau-Chen Cheng
IBM T.J. Watson Research Center
P.O.Box 704
Yorktown Heights, NY 10598

EMail: pau@watson.ibm.com
 

Robert Glenn
NIST
Building 820, Room 455
Gaithersburg, MD 20899

EMail: rob.glenn@nist.gov
 

翻訳者のアドレス

株式会社 NTTデータ
開発本部
馬場 達也

EMail: baba@rd.nttdata.co.jp

補遺

この付録には、既存の SHA-1 ライブラリを使用して HMAC-SHA-1 を実装するための参考コードを含みます。ここでは、SHA-1 ライブラリが、RFC 1321 に記述されている MD5 コードのような API を持っていることを想定しています。HMAC-MD5 のコードはこれと似ていて、「SHA」や「sha」という文字列を「MD5」や「md5」に置き換えるだけで得ることができます。HMAC-MD5 のコードは、RFC2104 にも掲載されています。

#ifndef SHA_DIGESTSIZE
#define SHA_DIGESTSIZE  20
#endif

#ifndef SHA_BLOCKSIZE
#define SHA_BLOCKSIZE   64
#endif

#ifndef MD5_DIGESTSIZE
#define MD5_DIGESTSIZE  16
#endif

#ifndef MD5_BLOCKSIZE
#define MD5_BLOCKSIZE   64
#endif

/* Function to print the digest */
void
pr_sha(FILE* fp, char* s, int t)
{
        int     i ;

        fprintf(fp, "0x") ;
        for (i = 0 ; i < t ; i++)
                fprintf(fp, "%02x", s[i]) ;
        fprintf(fp, "0) ;
}

void truncate
(
 char*   d1,   /* data to be truncated */
 char*   d2,   /* truncated data */
 int     len   /* length in bytes to keep */
)
{
        int     i ;
        for (i = 0 ; i < len ; i++) d2[i] = d1[i];
}

/* Function to compute the digest */
void
hmac_sha
(
 char*    k,     /* secret key */
 int      lk,    /* length of the key in bytes */
 char*    d,     /* data */
 int      ld,    /* length of data in bytes */
 char*    out,   /* output buffer, at least "t" bytes */
 int      t
)
{
        SHA_CTX ictx, octx ;
        char    isha[SHA_DIGESTSIZE], osha[SHA_DIGESTSIZE] ;
        char    key[SHA_DIGESTSIZE] ;
        char    buf[SHA_BLOCKSIZE] ;
        int     i ;

        if (lk > SHA_BLOCKSIZE) {

                SHA_CTX         tctx ;

                SHAInit(&tctx) ;
                SHAUpdate(&tctx, k, lk) ;
                SHAFinal(key, &tctx) ;

                k = key ;
                lk = SHA_DIGESTSIZE ;
        }

        /**** Inner Digest ****/

        SHAInit(&ictx) ;

        /* Pad the key for inner digest */
        for (i = 0 ; i < lk ; ++i) buf[i] = k[i] ^ 0x36 ;
        for (i = lk ; i < SHA_BLOCKSIZE ; ++i) buf[i] = 0x36 ;

        SHAUpdate(&ictx, buf, SHA_BLOCKSIZE) ;
        SHAUpdate(&ictx, d, ld) ;

        SHAFinal(isha, &ictx) ;

        /**** Outter Digest ****/

        SHAInit(&octx) ;

        /* Pad the key for outter digest */

        for (i = 0 ; i < lk ; ++i) buf[i] = k[i] ^ 0x5C ;
        for (i = lk ; i < SHA_BLOCKSIZE ; ++i) buf[i] = 0x5C ;

        SHAUpdate(&octx, buf, SHA_BLOCKSIZE) ;
        SHAUpdate(&octx, isha, SHA_DIGESTSIZE) ;

        SHAFinal(osha, &octx) ;

        /* truncate and print the results */
        t = t > SHA_DIGESTSIZE ? SHA_DIGESTSIZE : t ;
        truncate(osha, out, t) ;
        pr_sha(stdout, out, t) ;

}

著作権表記全文 

Copyright (C) The Internet Society (1997). All Rights Reserved.

This document and translations of it may be copied and furnished to others, and derivative works that comment on or otherwise explain it or assist in its implementation may be prepared, copied, published and distributed, in whole or in part, without restriction of any kind, provided that the above copyright notice and this paragraph are included on all such copies and derivative works. However, this document itself may not be modified in any way, such as by removing the copyright notice or references to the Internet Society or other Internet organizations, except as needed for the purpose of developing Internet standards in which case the procedures for copyrights defined in the Internet Standards process must be followed, or as required to translate it into languages other than English.

The limited permissions granted above are perpetual and will not be revoked by the Internet Society or its successors or assigns.

This document and the information contained herein is provided on an "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.