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

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

このコミットは、Go言語の標準ライブラリ crypto/rsa パッケージにおける GenerateKey および GenerateMultiPrimeKey 関数のドキュメンテーションを改善するものです。具体的には、これらの関数が受け取る random パラメータの役割について、より明確な説明を追加しています。

コミット

commit 9abe6d9dd0ee46b696f8c261417444777af19f6e
Author: Shenghou Ma <minux.ma@gmail.com>
Date:   Thu Feb 13 15:56:48 2014 -0500

    crypto/rsa: explain random parameter for GenerateKey and GenerateMultiPrimeKey.
    Fixes #6850.
    
    LGTM=agl
    R=golang-codereviews, agl
    CC=golang-codereviews
    https://golang.org/cl/60500046

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

https://github.com/golang/go/commit/9abe6d9dd0ee46b696f8c261417444777af19f6e

元コミット内容

crypto/rsa: explain random parameter for GenerateKey and GenerateMultiPrimeKey.
Fixes #6850.

LGTM=agl
R=golang-codereviews, agl
CC=golang-codereviews
https://golang.org/cl/60500046

変更の背景

このコミットの背景には、Go言語の crypto/rsa パッケージにおけるRSA鍵ペア生成関数のドキュメンテーションの明確化があります。特に、GenerateKey および GenerateMultiPrimeKey 関数が引数として受け取る random パラメータについて、その重要性と期待される値(例えば crypto/rand.Reader のような暗号論的に安全な乱数源)が十分に説明されていなかったことが問題視されました。

GitHub Issue #6850("crypto/rsa: document random parameter for GenerateKey")がこの変更の直接的なトリガーとなっています。このIssueでは、GenerateKey 関数の random 引数が何であるべきか、そしてなぜそれが重要なのかが明確でないという点が指摘されていました。暗号鍵の生成において、乱数源の品質は鍵のセキュリティに直結するため、このパラメータの適切な使用法を開発者に明確に伝えることは非常に重要です。不適切な乱数源を使用すると、生成される鍵が予測可能になり、結果として暗号システム全体のセキュリティが損なわれる可能性があります。

このコミットは、このような潜在的な誤用を防ぎ、開発者が安全なRSA鍵ペアを生成できるよう、ドキュメンテーションを改善することを目的としています。

前提知識の解説

RSA暗号

RSA (Rivest–Shamir–Adleman) は、公開鍵暗号方式の一つで、データの暗号化、デジタル署名、鍵交換などに広く用いられています。RSAの安全性は、大きな合成数の素因数分解が困難であるという数学的な問題に基づいています。

RSA鍵ペアは、公開鍵と秘密鍵の2つで構成されます。

  • 公開鍵 (Public Key): 誰にでも公開され、データの暗号化や署名の検証に使用されます。
  • 秘密鍵 (Private Key): 鍵の所有者のみが保持し、データの復号や署名の生成に使用されます。

RSA鍵ペアの生成には、通常、2つの大きな素数(pq)が必要です。これらの素数は、暗号論的に安全な乱数源から生成される必要があります。

暗号論的乱数 (Cryptographically Secure Random Number Generator, CSRNG)

暗号論的乱数とは、予測不可能な乱数を生成するアルゴリズムです。通常の乱数生成器(擬似乱数生成器、PRNG)とは異なり、暗号論的乱数は、その出力から過去の出力を推測したり、将来の出力を予測したりすることが非常に困難であるという特性を持っています。

暗号鍵の生成、セッションキーの生成、ノンス(一度だけ使用される数値)の生成など、セキュリティが要求される場面では、必ず暗号論的乱数を使用する必要があります。もし予測可能な乱数源が使われた場合、攻撃者は鍵を推測し、暗号化されたデータを解読したり、認証を突破したりすることが可能になります。

Go言語では、crypto/rand パッケージが暗号論的に安全な乱数源を提供します。特に crypto/rand.Reader は、OSが提供するエントロピー源(例: /dev/urandomCryptGenRandom)から乱数を読み取る io.Reader インターフェースを実装しており、暗号用途に適しています。

io.Reader インターフェース

Go言語の io.Reader インターフェースは、データを読み込むための汎用的なインターフェースです。

type Reader interface {
    Read(p []byte) (n int, err error)
}

Read メソッドは、バイトスライス p に最大 len(p) バイトのデータを読み込み、読み込んだバイト数 n とエラー err を返します。このインターフェースは、ファイル、ネットワーク接続、メモリバッファ、そして乱数源など、様々なデータソースからの読み込みを抽象化するために使用されます。

crypto/rsa.GenerateKey および GenerateMultiPrimeKey 関数が io.Reader を引数として受け取るのは、これにより様々な乱数源(例えば、テスト用の固定乱数源や、本番環境用の crypto/rand.Reader)を柔軟に指定できるようにするためです。しかし、セキュリティの観点からは、本番環境では必ず暗号論的に安全な乱数源を使用することが必須となります。

技術的詳細

このコミットは、crypto/rsa パッケージ内の GenerateKey および GenerateMultiPrimeKey 関数のコメントを修正することで、これらの関数が受け取る random パラメータの役割を明確にしています。

GenerateKey 関数

変更前:

// GenerateKey generates an RSA keypair of the given bit size.
func GenerateKey(random io.Reader, bits int) (priv *PrivateKey, err error) {
	return GenerateMultiPrimeKey(random, 2, bits)
}

変更後:

// GenerateKey generates an RSA keypair of the given bit size using the
// random source random (for example, crypto/rand.Reader).
func GenerateKey(random io.Reader, bits int) (priv *PrivateKey, err error) {
	return GenerateMultiPrimeKey(random, 2, bits)
}

変更点: コメントに「using the random source random (for example, crypto/rand.Reader)」という記述が追加されました。これにより、random 引数が単なる io.Reader ではなく、「乱数源」として機能し、具体例として crypto/rand.Reader が挙げられることで、開発者がどのような種類の乱数源を渡すべきかが明確になりました。これは、暗号論的に安全な乱数源を使用することの重要性を強調しています。

GenerateMultiPrimeKey 関数

変更前:

// GenerateMultiPrimeKey generates a multi-prime RSA keypair of the given bit
// size, as suggested in [1]. Although the public keys are compatible
// (actually, indistinguishable) from the 2-prime case, the private keys are
// not. Thus it may not be possible to export multi-prime private keys in
// certain formats or to subsequently import them into other code.

変更後:

// GenerateMultiPrimeKey generates a multi-prime RSA keypair of the given bit
// size and the given random source, as suggested in [1]. Although the public
// keys are compatible (actually, indistinguishable) from the 2-prime case,
// the private keys are not. Thus it may not be possible to export multi-prime
// private keys in certain formats or to subsequently import them into other
// code.

変更点: コメントに「and the given random source」という記述が追加されました。これにより、GenerateMultiPrimeKey 関数もまた、random 引数を通じて「乱数源」を受け取るという事実が明示されました。GenerateKey と同様に、この変更も乱数源の重要性を強調し、開発者が適切な乱数源を選択するよう促します。

これらの変更は、コードの動作自体には影響を与えませんが、APIの利用者がより安全な方法で鍵を生成できるよう、ドキュメンテーションの品質を向上させるものです。特に、暗号ライブラリにおいては、関数の引数の意味と期待される値が明確であることは、セキュリティ上の脆弱性を防ぐ上で極めて重要です。

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

src/pkg/crypto/rsa/rsa.go ファイルの以下の行が変更されました。

--- a/src/pkg/crypto/rsa/rsa.go
+++ b/src/pkg/crypto/rsa/rsa.go
@@ -120,16 +120,18 @@ func (priv *PrivateKey) Validate() error {
 	return nil
 }
 
-// GenerateKey generates an RSA keypair of the given bit size.\n
+// GenerateKey generates an RSA keypair of the given bit size using the\n
+// random source random (for example, crypto/rand.Reader).\n
 func GenerateKey(random io.Reader, bits int) (priv *PrivateKey, err error) {
 	return GenerateMultiPrimeKey(random, 2, bits)
 }
 
 // GenerateMultiPrimeKey generates a multi-prime RSA keypair of the given bit
-// size, as suggested in [1]. Although the public keys are compatible\n
-// (actually, indistinguishable) from the 2-prime case, the private keys are\n
-// not. Thus it may not be possible to export multi-prime private keys in\n
-// certain formats or to subsequently import them into other code.\n
+// size and the given random source, as suggested in [1]. Although the public\n
+// keys are compatible (actually, indistinguishable) from the 2-prime case,\n
+// the private keys are not. Thus it may not be possible to export multi-prime\n
+// private keys in certain formats or to subsequently import them into other\n
+// code.\n
 //
 // Table 1 in [2] suggests maximum numbers of primes for a given size.\n
 //

コアとなるコードの解説

このコミットにおけるコアとなるコードの変更は、Go言語の crypto/rsa パッケージ内の GenerateKey および GenerateMultiPrimeKey 関数のコメントの修正です。実際の関数のロジックや実装には一切変更が加えられていません。

GenerateKey 関数のコメント変更

元のコメント: // GenerateKey generates an RSA keypair of the given bit size.

変更後のコメント: // GenerateKey generates an RSA keypair of the given bit size using the // random source random (for example, crypto/rand.Reader).

この変更は、GenerateKey 関数が受け取る random 引数が、単なる io.Reader ではなく、暗号論的に安全な乱数源として機能することを明確にしています。特に「(for example, crypto/rand.Reader)」という具体的な例を挙げることで、開発者がこの引数に何を渡すべきか、そしてその重要性を直感的に理解できるようになります。crypto/rand.Reader はGo言語で推奨される暗号論的乱数源であり、これを使用することで生成されるRSA鍵のセキュリティが保証されます。

GenerateMultiPrimeKey 関数のコメント変更

元のコメント: // GenerateMultiPrimeKey generates a multi-prime RSA keypair of the given bit // size, as suggested in [1]. Although the public keys are compatible // (actually, indistinguishable) from the 2-prime case, the private keys are // not. Thus it may not be possible to export multi-prime private keys in // certain formats or to subsequently import them into other code.

変更後のコメント: // GenerateMultiPrimeKey generates a multi-prime RSA keypair of the given bit // size and the given random source, as suggested in [1]. Although the public // keys are compatible (actually, indistinguishable) from the 2-prime case, // the private keys are not. Thus it may not be possible to export multi-prime // private keys in certain formats or to subsequently import them into other // code.

この変更では、GenerateMultiPrimeKey 関数の説明に「and the given random source」というフレーズが追加されました。これにより、この関数もまた、鍵生成のために外部から提供される乱数源に依存していることが明示されます。GenerateKey 関数と同様に、この追加は、鍵のセキュリティを確保するために適切な乱数源の選択が不可欠であることを強調しています。

これらのコメントの変更は、Go言語のAPIドキュメンテーションの品質向上に貢献し、開発者が暗号ライブラリをより安全かつ適切に使用するためのガイドラインを提供します。暗号システムにおいて、乱数源の品質は最も重要な要素の一つであり、その適切な使用法を明確にすることは、潜在的なセキュリティ脆弱性を防ぐ上で不可欠です。

関連リンク

参考にした情報源リンク