[インデックス 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.1SEQUENCE
のタグと長さ。2d
は45バイトを示します。30 0d
: 内部のSEQUENCE
(AlgorithmIdentifier) のタグと長さ。0d
は13バイトを示します。06 09
: ASN.1OBJECT 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 署名に完全に対応するようになりました。
関連リンク
- RSA Laboratories: http://www.rsa.com/rsalabs/node.asp?id=2125
- Go CL 6208076: https://golang.org/cl/6208076
参考にした情報源リンク
- PKCS #1 v1.5 RSA signature DigestInfo:
- SHA-224 DigestInfo encoding:
- sha224WithRSAEncryption OID:
- Go crypto/rsa pkcs1v15.go hashPrefixes: