Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

[インデックス 13106] ファイルの概要

このコミットは、Go言語の crypto/rsa パッケージにおいて、PKCS #1 v1.5 署名スキームで使用されるハッシュプレフィックスに SHA-224 のサポートを追加するものです。これにより、RSA 署名において SHA-224 ハッシュアルゴリズムが適切に利用できるようになります。

コミット

commit 053e4edd80f9d15a480585cfa82110ac8543dc97
Author: Russ Cox <rsc@golang.org>
Date:   Mon May 21 14:10:16 2012 -0400

    crypto/rsa: add SHA-224 hash prefix
    
    http://www.rsa.com/rsalabs/node.asp?id=2125:
    
    NOTE: A new OID has been defined for the combination
    of the v1.5 signature scheme and the SHA-224 hash function:
            sha224WithRSAEncryption OBJECT IDENTIFIER ::=
    Like the other sha*WithRSAEncryption OIDs in PKCS #1 v2.1,
    this OID has NULL parameters.
    The DigestInfo encoding for SHA-224 (see Section 9.2, Note 1) is:
            (0x)30 2d 30 0d 06 09 60 86 48 01 65 03 04 02 04 05 00 04 1c || H
    
    R=golang-dev, agl
    CC=golang-dev
    https://golang.org/cl/6208076

GitHub上でのコミットページへのリンク

https://github.com/golang/go/commit/053e4edd80f9d15a480585cfa82110ac8543dc97

元コミット内容

crypto/rsa: add SHA-224 hash prefix

このコミットは、crypto/rsa パッケージに SHA-224 ハッシュプレフィックスを追加するものです。これは、PKCS #1 v1.5 署名スキームにおいて SHA-224 ハッシュ関数を使用するために必要な変更です。コミットメッセージには、RSA Laboratories のウェブサイトで定義されている SHA-224 と RSA 暗号化の組み合わせのための新しい OID (Object Identifier) と、SHA-224 の DigestInfo エンコーディングのバイト列が記載されています。

変更の背景

この変更の背景には、PKCS #1 標準の進化と、新しいハッシュアルゴリズムである SHA-224 の採用があります。PKCS #1 v2.1 では、sha224WithRSAEncryption という新しい OID が定義され、SHA-224 ハッシュ関数と v1.5 署名スキームの組み合わせが標準化されました。

RSA 署名では、署名されるデータのハッシュ値だけでなく、使用されたハッシュアルゴリズムの種類も署名データの一部として含める必要があります。これは DigestInfo と呼ばれる構造体で表現され、ASN.1 (Abstract Syntax Notation One) DER (Distinguished Encoding Rules) 形式でエンコードされます。Go の crypto/rsa パッケージでは、効率化のために、各ハッシュアルゴリズムに対応する DigestInfo の固定プレフィックスを hashPrefixes マップに事前に定義しています。

SHA-224 が新しい標準として追加されたため、Go の crypto/rsa パッケージがこの新しいハッシュアルゴリズムをサポートし、PKCS #1 v1.5 署名で正しく利用できるようにするために、対応する DigestInfo プレフィックスを hashPrefixes マップに追加する必要がありました。これにより、Go アプリケーションが SHA-224 を使用した RSA 署名を生成および検証できるようになります。

前提知識の解説

PKCS #1 v1.5 RSA 署名

PKCS #1 (Public-Key Cryptography Standards #1) は、RSA 暗号アルゴリズムの実装に関する標準を定義しています。その中でも v1.5 は、RSA 署名スキームの初期のバージョンであり、広く利用されています。

PKCS #1 v1.5 署名では、署名対象のメッセージのハッシュ値を計算し、そのハッシュ値とハッシュアルゴリズムの識別子を組み合わせた DigestInfo 構造体を生成します。この DigestInfo は、特定のパディングスキーム (EMSA-PKCS1-v1_5) に従ってパディングされ、最終的に RSA 秘密鍵で暗号化(署名)されます。検証時には、公開鍵で復号し、パディングを解除して DigestInfo を抽出し、メッセージのハッシュ値とハッシュアルゴリズムが一致するかを確認します。

DigestInfo 構造体

DigestInfo は、署名されるデータのハッシュ値と、そのハッシュ値を計算するために使用されたハッシュアルゴリズムの識別子を組み合わせた ASN.1 構造体です。これは、署名がどのハッシュアルゴリズムを使用して生成されたかを検証者が判断できるようにするために不可欠です。

DigestInfo の ASN.1 定義は以下のようになります。

DigestInfo ::= SEQUENCE {
    digestAlgorithm AlgorithmIdentifier,
    digest OCTET STRING
}

AlgorithmIdentifier ::= SEQUENCE {
    algorithm OBJECT IDENTIFIER,
    parameters ANY DEFINED BY algorithm OPTIONAL
}
  • digestAlgorithm: ハッシュアルゴリズムを識別する AlgorithmIdentifier です。これには、ハッシュアルゴリズムの OID と、必要に応じてパラメータが含まれます。
  • digest: 実際のハッシュ値(メッセージダイジェスト)を含むオクテット文字列です。

ASN.1 DER エンコーディング

ASN.1 (Abstract Syntax Notation One) は、データ構造を定義するための標準的な記法です。DER (Distinguished Encoding Rules) は、ASN.1 で定義されたデータ構造をバイト列にエンコードするための特定のルールセットです。DER は、同じデータ構造に対して常に同じバイト列を生成するという特徴があり、暗号化やデジタル署名においてデータの整合性を保証するために重要です。

DigestInfo 構造体は、PKCS #1 v1.5 署名スキームで使用される前に、DER 形式でエンコードされます。このエンコードされたバイト列が、RSA 署名操作の入力の一部となります。

OID (Object Identifier)

OID (Object Identifier) は、情報オブジェクトを一意に識別するための国際標準の識別子です。階層的な構造を持ち、ドットで区切られた一連の数字で表現されます(例: 1.2.840.113549.1.1.14)。暗号技術の分野では、特定のアルゴリズム、証明書のフィールド、ポリシーなどを識別するために広く使用されます。

このコミットで言及されている sha224WithRSAEncryption の OID は 1.2.840.113549.1.1.14 です。これは、PKCS #1 v1.5 署名スキームと SHA-224 ハッシュ関数の組み合わせを識別します。

SHA-224 ハッシュアルゴリズム

SHA-224 (Secure Hash Algorithm 224) は、NIST (National Institute of Standards and Technology) によって開発された暗号学的ハッシュ関数の一つです。SHA-256 をベースにしており、224ビット(28バイト)のハッシュ値を出力します。SHA-224 は、データの完全性を検証したり、デジタル署名の一部として使用されたりします。

技術的詳細

Go言語の crypto/rsa パッケージでは、PKCS #1 v1.5 署名スキームを実装する際に、pkcs1v15.go ファイル内の hashPrefixes というマップを利用しています。このマップは map[crypto.Hash][]byte 型で、各ハッシュアルゴリズム (crypto.Hash 型の定数) に対応する DigestInfo 構造体の DER エンコードされたバイト列のプレフィックスを格納しています。

署名処理では、まず署名対象のデータのハッシュ値を計算し、次にそのハッシュアルゴリズムに対応するプレフィックスを hashPrefixes マップから取得します。このプレフィックスと計算されたハッシュ値を連結することで、完全な DigestInfo の DER エンコードされたバイト列が生成されます。このバイト列が、RSA 署名操作の入力として使用されます。

このコミットでは、SHA-224 ハッシュアルゴリズムのサポートを追加するために、hashPrefixes マップに crypto.SHA224 に対応する新しいエントリが追加されました。コミットメッセージに記載されている SHA-224 の DigestInfo エンコーディングのバイト列は、以下の通りです。

30 2d 30 0d 06 09 60 86 48 01 65 03 04 02 04 05 00 04 1c

このバイト列は、SHA-224 の DigestInfo 構造体を DER エンコードした際の固定プレフィックスです。

  • 30 2d: ASN.1 SEQUENCE のタグと長さ。2d は45バイトを示します。
  • 30 0d: 内部の SEQUENCE (AlgorithmIdentifier) のタグと長さ。0d は13バイトを示します。
  • 06 09: ASN.1 OBJECT IDENTIFIER のタグと長さ。09 は9バイトを示します。
  • 60 86 48 01 65 03 04 02 04: SHA-224 の OID (2.16.840.1.101.3.4.2.4) の DER エンコード。
  • 05 00: NULL パラメータ。SHA-224 の AlgorithmIdentifier はパラメータを持ちません。
  • 04 1c: OCTET STRING のタグと長さ。1c は28バイトを示し、これは SHA-224 のハッシュ値の長さ(224ビット = 28バイト)に対応します。

このプレフィックスの後に、実際の SHA-224 ハッシュ値(28バイト)が連結されて、完全な DigestInfo が形成されます。

コアとなるコードの変更箇所

--- a/src/pkg/crypto/rsa/pkcs1v15.go
+++ b/src/pkg/crypto/rsa/pkcs1v15.go
@@ -151,6 +151,7 @@ func nonZeroRandomBytes(s []byte, rand io.Reader) (err error) {
 var hashPrefixes = map[crypto.Hash][]byte{
  	crypto.MD5:       {0x30, 0x20, 0x30, 0x0c, 0x06, 0x08, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x02, 0x05, 0x05, 0x00, 0x04, 0x10},\
  	crypto.SHA1:      {0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1a, 0x05, 0x00, 0x04, 0x14},\
+	crypto.SHA224:    {0x30, 0x2d, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x04, 0x05, 0x00, 0x04, 0x1c},\
  	crypto.SHA256:    {0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05, 0x00, 0x04, 0x20},\
  	crypto.SHA384:    {0x30, 0x41, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x02, 0x05, 0x00, 0x04, 0x30},\
  	crypto.SHA512:    {0x30, 0x51, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03, 0x05, 0x00, 0x04, 0x40},\

コアとなるコードの解説

このコミットの変更は、src/pkg/crypto/rsa/pkcs1v15.go ファイル内の hashPrefixes マップに新しいエントリを1行追加するだけです。

追加された行は以下の通りです。

crypto.SHA224:    {0x30, 0x2d, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x04, 0x05, 0x00, 0x04, 0x1c},

この行は、crypto.SHA224 というハッシュアルゴリズムの識別子に対して、対応する DigestInfo の DER エンコードされたプレフィックスバイト列を関連付けています。これにより、Go の crypto/rsa パッケージが PKCS #1 v1.5 署名スキームで SHA-224 を使用する際に、正しい DigestInfo 構造体を構築できるようになります。

具体的には、SignPKCS1v15 のような関数が crypto.SHA224 を引数として受け取った場合、このマップから対応するバイト列を取得し、計算された SHA-224 ハッシュ値と結合して、RSA 署名操作の準備を行います。この変更により、Go の標準ライブラリが SHA-224 を用いた RSA 署名に完全に対応するようになりました。

関連リンク

参考にした情報源リンク