github.com/shogo82148/std@v1.22.1-0.20240327122250-4e474527810c/crypto/rsa/rsa.go (about) 1 // Copyright 2009 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 // Package rsaは、PKCS #1およびRFC 8017で指定されたRSA暗号化を実装します。 6 // 7 // RSAは、このパッケージで使用される単一の基本操作であり、公開鍵暗号化または公開鍵署名のいずれかを実装するために使用されます。 8 // 9 // RSAの暗号化および署名の元となる仕様は、PKCS #1であり、デフォルトでは "RSA暗号化"および "RSA署名"という用語は、通常PKCS #1バージョン1.5を指します。ただし、その仕様には欠陥があり、新しい設計はできる限りOAEPとPSSと呼ばれるバージョン2を使用するべきです。 10 // 11 // このパッケージには2つのセットのインタフェースが含まれています。より抽象的なインタフェースが不要な場合は、v1.5 / OAEPでの暗号化/復号化、およびv1.5 / PSSでの署名/検証のための関数があります。公開鍵原則に対して抽象化する必要がある場合は、PrivateKey型がcryptoパッケージのDecrypterおよびSignerインタフェースを実装します。 12 // 13 // このパッケージの操作は、一部の操作を除いて、一定の時間アルゴリズムを使用して実装されています。[GenerateKey]、[PrivateKey.Precompute]、および[PrivateKey.Validate]を除くすべての他の操作は、関連する値のビットサイズのみ漏洩し、すべての値は選択したキーサイズに依存します。 14 package rsa 15 16 import ( 17 "github.com/shogo82148/std/crypto" 18 "github.com/shogo82148/std/crypto/internal/bigmod" 19 "github.com/shogo82148/std/errors" 20 "github.com/shogo82148/std/hash" 21 "github.com/shogo82148/std/io" 22 "github.com/shogo82148/std/math/big" 23 ) 24 25 // PublicKeyは、RSAキーの公開部分を表します。 26 // 27 // このライブラリでは、モジュラスNの値は秘密と見なされ、タイミングサイドチャネルを通じた漏洩から保護されます。 28 // しかし、指数Eの値やNの正確なビットサイズは同様に保護されません。 29 type PublicKey struct { 30 N *big.Int 31 E int 32 } 33 34 // Size はバイト単位での剰余サイズを返します。この公開鍵による生の署名および暗号文のサイズは同じです。 35 func (pub *PublicKey) Size() int 36 37 // Equalは、pubとxが同じ値を持っているかどうかを報告します。 38 func (pub *PublicKey) Equal(x crypto.PublicKey) bool 39 40 // OAEPOptionsは、crypto.Decrypterインタフェースを使用してOAEP復号化にオプションを渡すためのインタフェースです。 41 type OAEPOptions struct { 42 // Hashはマスク生成時に使用されるハッシュ関数です。 43 Hash crypto.Hash 44 45 // MGFHashはMGF1で使用されるハッシュ関数です。 46 // ゼロの場合、代わりにHashが使用されます。 47 MGFHash crypto.Hash 48 49 // ラベルは、暗号化の際に使用される値と等しい任意のバイトストリングです。 50 Label []byte 51 } 52 53 // PrivateKeyはRSAキーを表します 54 type PrivateKey struct { 55 PublicKey 56 D *big.Int 57 Primes []*big.Int 58 59 // PrecomputedはRSAの操作を高速化するために事前計算された値を含んでいます。 60 // 利用可能な場合は、PrivateKey.Precomputeを呼び出して生成されなければなりません。 61 // また、変更してはいけません。 62 Precomputed PrecomputedValues 63 } 64 65 // Publicはprivに対応する公開鍵を返します。 66 func (priv *PrivateKey) Public() crypto.PublicKey 67 68 // Equalはprivとxが等価な値を持つかどうかを報告します。事前計算された値は無視されます。 69 func (priv *PrivateKey) Equal(x crypto.PrivateKey) bool 70 71 // privという秘密鍵を使用して、乱数をrandから読み取り、署名digestを生成します。optsが *[PSSOptions] の場合、PSSアルゴリズムが使用されます。それ以外の場合は、PKCS #1 v1.5が使用されます。digestは、opts.HashFunc()を使用して入力メッセージのハッシュ値を計算した結果でなければなりません。 72 // 73 // このメソッドは [crypto.Signer] を実装しており、例えばハードウェアモジュールに保持される秘密部分をサポートするインターフェースです。一般的な使用法では、このパッケージ内のSign*関数を直接使用するべきです。 74 func (priv *PrivateKey) Sign(rand io.Reader, digest []byte, opts crypto.SignerOpts) ([]byte, error) 75 76 // Decryptはprivで暗号文を復号化します。optsがnilまたは *[PKCS1v15DecryptOptions] 型の場合、PKCS #1 v1.5 復号化が実行されます。それ以外の場合、optsは *[OAEPOptions] 型でなければなりませんし、OAEP 復号化が行われます。 77 func (priv *PrivateKey) Decrypt(rand io.Reader, ciphertext []byte, opts crypto.DecrypterOpts) (plaintext []byte, err error) 78 79 type PrecomputedValues struct { 80 Dp, Dq *big.Int 81 Qinv *big.Int 82 83 // CRTValuesは3番目以降の素数に使用されます。歴史的な偶然により、 84 // 最初の2つの素数のためのCRTはPKCS #1で異なる方法で処理されますが、 85 // この相互運用性は十分に重要です。 86 // 87 // 廃止予定:これらの値は、後方互換性のためにまだPrecomputeによって 88 // 埋められていますが、使用されていません。マルチプライムRSAは非常に稀ですが、 89 // 複雑さを制限するためにこのパッケージでCRTの最適化なしで実装されています。 90 CRTValues []CRTValue 91 92 n, p, q *bigmod.Modulus 93 } 94 95 // CRTValueには事前計算された中国剰余定理の値が含まれています。 96 type CRTValue struct { 97 Exp *big.Int 98 Coeff *big.Int 99 R *big.Int 100 } 101 102 // Validateはキーに基本的な正当性チェックを行います。 103 // キーが正当であれば、nilを返します。それ以外の場合は、問題を説明するエラーが返されます。 104 func (priv *PrivateKey) Validate() error 105 106 // GenerateKeyは指定されたビットサイズのランダムなRSA秘密鍵を生成します。 107 // 108 // ほとんどのアプリケーションはrandとして[crypto/rand.Reader]を使用するべきです。注意:返される鍵は、randから読み取られたバイトに従属的に決定されず、呼び出しやバージョンによって変わる可能性があります。 109 func GenerateKey(random io.Reader, bits int) (*PrivateKey, error) 110 111 // GenerateMultiPrimeKeyは指定されたビットサイズとランダムソースで、マルチプライムRSA鍵ペアを生成します。 112 // 113 // "[On the Security of Multi-prime RSA]"のテーブル1には、与えられたビットサイズの最大プライム数が示されています。 114 // 115 // 公開鍵は2つのプライムの場合と互換性がありますが、秘密鍵は異なります。したがって、特定の形式でマルチプライムの秘密鍵をエクスポートしたり、他のコードに後からインポートすることができない場合があります。 116 // 117 // このパッケージではマルチプライムRSAのCRT最適化を実装していないため、2つ以上のプライムを持つキーのパフォーマンスは悪くなります。 118 // 119 // Deprecated: 上記のセキュリティ、互換性、およびパフォーマンスの理由により、2つ以外のプライム数でこの関数を使用することはお勧めしません。代わりに [GenerateKey] を使用してください。 120 // 121 // [On the Security of Multi-prime RSA]: http://www.cacr.math.uwaterloo.ca/techreports/2006/cacr2006-16.pdf 122 func GenerateMultiPrimeKey(random io.Reader, nprimes int, bits int) (*PrivateKey, error) 123 124 // ErrMessageTooLong は、鍵のサイズに対して大きすぎるメッセージを暗号化または署名しようとした場合に返されます。 [SignPSS] を使用する場合、塩のサイズが大きすぎる場合にも返されることがあります。 125 var ErrMessageTooLong = errors.New("crypto/rsa: message too long for RSA key size") 126 127 // EncryptOAEPはRSA-OAEPで与えられたメッセージを暗号化します。 128 // 129 // OAEPはランダムオラクルとして使用されるハッシュ関数でパラメータ化されています。 130 // 暗号化と復号化は同じハッシュ関数を使用する必要があります。 131 // sha256.New()は妥当な選択肢です。 132 // 133 // ランダムパラメータはエントロピーのソースとして使用され、同じメッセージを2回暗号化しても 134 // 同じ暗号文にならないようにします。 135 // ほとんどのアプリケーションでは、[crypto/rand.Reader]をランダムとして使用するべきです。 136 // 137 // ラベルパラメータには暗号化されない任意のデータを含めることができます。 138 // ただし、このデータはメッセージに重要な文脈を与えます。 139 // 例えば、特定の公開鍵が2つのタイプのメッセージを暗号化する場合、異なるラベル値を使用して 140 // 攻撃者が別の目的で暗号文を使用できないようにすることができます。 141 // 必要ない場合は空にしても構いません。 142 // 143 // メッセージは公開モジュラスの長さからハッシュの2倍の長さを引いた値より長くすることはできません。 144 // さらに2を引いた長さ以下である必要があります。 145 func EncryptOAEP(hash hash.Hash, random io.Reader, pub *PublicKey, msg []byte, label []byte) ([]byte, error) 146 147 // ErrDecryptionはメッセージの復号に失敗したことを表します。 148 // 適応攻撃を避けるため、故意に曖昧さを持たせています。 149 var ErrDecryption = errors.New("crypto/rsa: decryption error") 150 151 // ErrVerificationは署名を検証できなかったことを表します。 152 // 自己適応攻撃を避けるために、意図的にあいまいです。 153 var ErrVerification = errors.New("crypto/rsa: verification error") 154 155 // Precomputeは未来の秘密鍵操作を高速化するためのいくつかの計算を実行します。 156 func (priv *PrivateKey) Precompute() 157 158 // DecryptOAEPはRSA-OAEPを使用して暗号文を復号化します。 159 // 160 // OAEPはランダムオラクルとして使用されるハッシュ関数でパラメータ化されます。 161 // 特定のメッセージの暗号化および復号化は、同じハッシュ関数を使用する必要があります。 162 // sha256.New()が妥当な選択肢です。 163 // 164 // ランダムパラメータは旧式で無視され、nilであることができます。 165 // 166 // ラベルパラメータは暗号化時に指定した値と一致する必要があります。 167 // 詳細については、 [EncryptOAEP] を参照してください。 168 func DecryptOAEP(hash hash.Hash, random io.Reader, priv *PrivateKey, ciphertext []byte, label []byte) ([]byte, error)