crypto/rsa: deprecate PKCS#1 v1.5 encryption

Fixes #75302

Change-Id: I6a6a6964c2b3b33bfb34b9677a57610b933bbfab
Reviewed-on: https://go-review.googlesource.com/c/go/+/701436
Reviewed-by: Daniel McCarney <daniel@binaryparadox.net>
Reviewed-by: Mark Freeman <markfreeman@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Auto-Submit: Filippo Valsorda <filippo@golang.org>
Reviewed-by: Michael Pratt <mpratt@google.com>
This commit is contained in:
Filippo Valsorda 2025-09-07 16:07:43 +02:00 committed by Gopher Robot
parent d55ecea9e5
commit c58d075e9a
3 changed files with 34 additions and 9 deletions

4
api/next/75302.txt Normal file
View file

@ -0,0 +1,4 @@
pkg crypto/rsa, func DecryptPKCS1v15 //deprecated #75302
pkg crypto/rsa, func DecryptPKCS1v15SessionKey //deprecated #75302
pkg crypto/rsa, func EncryptPKCS1v15 //deprecated #75302
pkg crypto/rsa, type PKCS1v15DecryptOptions //deprecated #75302

View file

@ -0,0 +1,2 @@
Unsafe PKCS #1 v1.5 encryption padding (implemented by [EncryptPKCS1v15],
[DecryptPKCS1v15], and [DecryptPKCS1v15SessionKey]) is now deprecated.

View file

@ -18,6 +18,12 @@ import (
// PKCS1v15DecryptOptions is for passing options to PKCS #1 v1.5 decryption using // PKCS1v15DecryptOptions is for passing options to PKCS #1 v1.5 decryption using
// the [crypto.Decrypter] interface. // the [crypto.Decrypter] interface.
//
// Deprecated: PKCS #1 v1.5 encryption is dangerous and should not be used.
// See [draft-irtf-cfrg-rsa-guidance-05] for more information. Use
// [EncryptOAEP] and [DecryptOAEP] instead.
//
// [draft-irtf-cfrg-rsa-guidance-05]: https://www.ietf.org/archive/id/draft-irtf-cfrg-rsa-guidance-05.html#name-rationale
type PKCS1v15DecryptOptions struct { type PKCS1v15DecryptOptions struct {
// SessionKeyLen is the length of the session key that is being // SessionKeyLen is the length of the session key that is being
// decrypted. If not zero, then a padding error during decryption will // decrypted. If not zero, then a padding error during decryption will
@ -37,8 +43,11 @@ type PKCS1v15DecryptOptions struct {
// deterministically on the bytes read from random, and may change // deterministically on the bytes read from random, and may change
// between calls and/or between versions. // between calls and/or between versions.
// //
// WARNING: use of this function to encrypt plaintexts other than // Deprecated: PKCS #1 v1.5 encryption is dangerous and should not be used.
// session keys is dangerous. Use RSA OAEP in new protocols. // See [draft-irtf-cfrg-rsa-guidance-05] for more information. Use
// [EncryptOAEP] and [DecryptOAEP] instead.
//
// [draft-irtf-cfrg-rsa-guidance-05]: https://www.ietf.org/archive/id/draft-irtf-cfrg-rsa-guidance-05.html#name-rationale
func EncryptPKCS1v15(random io.Reader, pub *PublicKey, msg []byte) ([]byte, error) { func EncryptPKCS1v15(random io.Reader, pub *PublicKey, msg []byte) ([]byte, error) {
if fips140only.Enabled { if fips140only.Enabled {
return nil, errors.New("crypto/rsa: use of PKCS#1 v1.5 encryption is not allowed in FIPS 140-only mode") return nil, errors.New("crypto/rsa: use of PKCS#1 v1.5 encryption is not allowed in FIPS 140-only mode")
@ -91,14 +100,17 @@ func EncryptPKCS1v15(random io.Reader, pub *PublicKey, msg []byte) ([]byte, erro
return rsa.Encrypt(fk, em) return rsa.Encrypt(fk, em)
} }
// DecryptPKCS1v15 decrypts a plaintext using RSA and the padding scheme from PKCS #1 v1.5. // DecryptPKCS1v15 decrypts a plaintext using RSA and the padding scheme from
// The random parameter is legacy and ignored, and it can be nil. // PKCS #1 v1.5. The random parameter is legacy and ignored, and it can be nil.
// //
// Note that whether this function returns an error or not discloses secret // Deprecated: PKCS #1 v1.5 encryption is dangerous and should not be used.
// information. If an attacker can cause this function to run repeatedly and // Whether this function returns an error or not discloses secret information.
// learn whether each instance returned an error then they can decrypt and // If an attacker can cause this function to run repeatedly and learn whether
// forge signatures as if they had the private key. See // each instance returned an error then they can decrypt and forge signatures as
// DecryptPKCS1v15SessionKey for a way of solving this problem. // if they had the private key. See [draft-irtf-cfrg-rsa-guidance-05] for more
// information. Use [EncryptOAEP] and [DecryptOAEP] instead.
//
// [draft-irtf-cfrg-rsa-guidance-05]: https://www.ietf.org/archive/id/draft-irtf-cfrg-rsa-guidance-05.html#name-rationale
func DecryptPKCS1v15(random io.Reader, priv *PrivateKey, ciphertext []byte) ([]byte, error) { func DecryptPKCS1v15(random io.Reader, priv *PrivateKey, ciphertext []byte) ([]byte, error) {
if err := checkPublicKeySize(&priv.PublicKey); err != nil { if err := checkPublicKeySize(&priv.PublicKey); err != nil {
return nil, err return nil, err
@ -160,6 +172,13 @@ func DecryptPKCS1v15(random io.Reader, priv *PrivateKey, ciphertext []byte) ([]b
// Standard PKCS #1”, Daniel Bleichenbacher, Advances in Cryptology (Crypto '98) // Standard PKCS #1”, Daniel Bleichenbacher, Advances in Cryptology (Crypto '98)
// - [1] RFC 3218, Preventing the Million Message Attack on CMS, // - [1] RFC 3218, Preventing the Million Message Attack on CMS,
// https://www.rfc-editor.org/rfc/rfc3218.html // https://www.rfc-editor.org/rfc/rfc3218.html
//
// Deprecated: PKCS #1 v1.5 encryption is dangerous and should not be used. The
// protections implemented by this function are limited and fragile, as
// explained above. See [draft-irtf-cfrg-rsa-guidance-05] for more information.
// Use [EncryptOAEP] and [DecryptOAEP] instead.
//
// [draft-irtf-cfrg-rsa-guidance-05]: https://www.ietf.org/archive/id/draft-irtf-cfrg-rsa-guidance-05.html#name-rationale
func DecryptPKCS1v15SessionKey(random io.Reader, priv *PrivateKey, ciphertext []byte, key []byte) error { func DecryptPKCS1v15SessionKey(random io.Reader, priv *PrivateKey, ciphertext []byte, key []byte) error {
if err := checkPublicKeySize(&priv.PublicKey); err != nil { if err := checkPublicKeySize(&priv.PublicKey); err != nil {
return err return err