Source File
pkcs1v15.go
Belonging Package
crypto/rsa
// Copyright 2009 The Go Authors. All rights reserved.// Use of this source code is governed by a BSD-style// license that can be found in the LICENSE file.package rsaimport ()// This file implements encryption and decryption using PKCS #1 v1.5 padding.// PKCS1v15DecryptOptions is for passing options to PKCS #1 v1.5 decryption using// 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-rationaletype PKCS1v15DecryptOptions struct {// SessionKeyLen is the length of the session key that is being// decrypted. If not zero, then a padding error during decryption will// cause a random plaintext of this length to be returned rather than// an error. These alternatives happen in constant time.SessionKeyLen int}// EncryptPKCS1v15 encrypts the given message with RSA and the padding// scheme from PKCS #1 v1.5. The message must be no longer than the// length of the public modulus minus 11 bytes.//// The random parameter is used as a source of entropy to ensure that encrypting// the same message twice doesn't result in the same ciphertext. Since Go 1.26,// a secure source of random bytes is always used, and the Reader is ignored// unless GODEBUG=cryptocustomrand=1 is set. This setting will be removed in a// future Go release. Instead, use [testing/cryptotest.SetGlobalRandom].//// 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-rationalefunc ( io.Reader, *PublicKey, []byte) ([]byte, error) {if fips140only.Enforced() {return nil, errors.New("crypto/rsa: use of PKCS#1 v1.5 encryption is not allowed in FIPS 140-only mode")}if := checkPublicKeySize(); != nil {return nil,}:= .Size()if len() > -11 {return nil, ErrMessageTooLong}if boring.Enabled && rand.IsDefaultReader() {, := boringPublicKey()if != nil {return nil,}return boring.EncryptRSAPKCS1(, )}boring.UnreachableExceptTests()= rand.CustomReader()// EM = 0x00 || 0x02 || PS || 0x00 || M:= make([]byte, )[1] = 2, := [2:len()-len()-1], [len()-len():]:= nonZeroRandomBytes(, )if != nil {return nil,}[len()-len()-1] = 0copy(, )if boring.Enabled {var *boring.PublicKeyRSA, = boringPublicKey()if != nil {return nil,}return boring.EncryptRSANoPadding(, )}, := fipsPublicKey()if != nil {return nil,}return rsa.Encrypt(, )}// DecryptPKCS1v15 decrypts a plaintext using RSA and the padding scheme from// PKCS #1 v1.5. The random parameter is legacy and ignored, and it can be nil.//// Deprecated: PKCS #1 v1.5 encryption is dangerous and should not be used.// Whether this function returns an error or not discloses secret information.// If an attacker can cause this function to run repeatedly and learn whether// each instance returned an error then they can decrypt and forge signatures as// 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-rationalefunc ( io.Reader, *PrivateKey, []byte) ([]byte, error) {if := checkPublicKeySize(&.PublicKey); != nil {return nil,}if boring.Enabled {, := boringPrivateKey()if != nil {return nil,}, := boring.DecryptRSAPKCS1(, )if != nil {return nil, ErrDecryption}return , nil}, , , := decryptPKCS1v15(, )if != nil {return nil,}if == 0 {return nil, ErrDecryption}return [:], nil}// DecryptPKCS1v15SessionKey decrypts a session key using RSA and the padding// scheme from PKCS #1 v1.5. The random parameter is legacy and ignored, and it// can be nil.//// DecryptPKCS1v15SessionKey returns an error if the ciphertext is the wrong// length or if the ciphertext is greater than the public modulus. Otherwise, no// error is returned. If the padding is valid, the resulting plaintext message// is copied into key. Otherwise, key is unchanged. These alternatives occur in// constant time. It is intended that the user of this function generate a// random session key beforehand and continue the protocol with the resulting// value.//// Note that if the session key is too small then it may be possible for an// attacker to brute-force it. If they can do that then they can learn whether a// random value was used (because it'll be different for the same ciphertext)// and thus whether the padding was correct. This also defeats the point of this// function. Using at least a 16-byte key will protect against this attack.//// This method implements protections against Bleichenbacher chosen ciphertext// attacks [0] described in RFC 3218 Section 2.3.2 [1]. While these protections// make a Bleichenbacher attack significantly more difficult, the protections// are only effective if the rest of the protocol which uses// DecryptPKCS1v15SessionKey is designed with these considerations in mind. In// particular, if any subsequent operations which use the decrypted session key// leak any information about the key (e.g. whether it is a static or random// key) then the mitigations are defeated. This method must be used extremely// carefully, and typically should only be used when absolutely necessary for// compatibility with an existing protocol (such as TLS) that is designed with// these properties in mind.//// - [0] “Chosen Ciphertext Attacks Against Protocols Based on the RSA Encryption// Standard PKCS #1”, Daniel Bleichenbacher, Advances in Cryptology (Crypto '98)// - [1] RFC 3218, Preventing the Million Message Attack on CMS,// 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-rationalefunc ( io.Reader, *PrivateKey, []byte, []byte) error {if := checkPublicKeySize(&.PublicKey); != nil {return}:= .Size()if -(len()+3+8) < 0 {return ErrDecryption}, , , := decryptPKCS1v15(, )if != nil {return}if len() != {// This should be impossible because decryptPKCS1v15 always// returns the full slice.return ErrDecryption}&= subtle.ConstantTimeEq(int32(len()-), int32(len()))subtle.ConstantTimeCopy(, , [len()-len():])return nil}// decryptPKCS1v15 decrypts ciphertext using priv. It returns one or zero in// valid that indicates whether the plaintext was correctly structured.// In either case, the plaintext is returned in em so that it may be read// independently of whether it was valid in order to maintain constant memory// access patterns. If the plaintext was valid then index contains the index of// the original message in em, to allow constant time padding removal.func decryptPKCS1v15( *PrivateKey, []byte) ( int, []byte, int, error) {if fips140only.Enforced() {return 0, nil, 0, errors.New("crypto/rsa: use of PKCS#1 v1.5 encryption is not allowed in FIPS 140-only mode")}:= .Size()if < 11 {= ErrDecryptionreturn 0, nil, 0,}if boring.Enabled {var *boring.PrivateKeyRSA, = boringPrivateKey()if != nil {return 0, nil, 0,}, = boring.DecryptRSANoPadding(, )if != nil {return 0, nil, 0, ErrDecryption}} else {, := fipsPrivateKey()if != nil {return 0, nil, 0,}, = rsa.DecryptWithoutCheck(, )if != nil {return 0, nil, 0, ErrDecryption}}:= subtle.ConstantTimeByteEq([0], 0):= subtle.ConstantTimeByteEq([1], 2)// The remainder of the plaintext must be a string of non-zero random// octets, followed by a 0, followed by the message.// lookingForIndex: 1 iff we are still looking for the zero.// index: the offset of the first zero byte.:= 1for := 2; < len(); ++ {:= subtle.ConstantTimeByteEq([], 0)= subtle.ConstantTimeSelect(&, , )= subtle.ConstantTimeSelect(, 0, )}// The PS padding must be at least 8 bytes long, and it starts two// bytes into em.:= subtle.ConstantTimeLessOrEq(2+8, )= & & (^ & 1) &= subtle.ConstantTimeSelect(, +1, 0)return , , , nil}// nonZeroRandomBytes fills the given slice with non-zero random octets.func nonZeroRandomBytes( []byte, io.Reader) ( error) {_, = io.ReadFull(, )if != nil {return}for := 0; < len(); ++ {for [] == 0 {_, = io.ReadFull(, [:+1])if != nil {return}// In tests, the PRNG may return all zeros so we do// this to break the loop.[] ^= 0x42}}return}
![]() |
The pages are generated with Golds v0.8.3-preview. (GOOS=linux GOARCH=amd64) Golds is a Go 101 project developed by Tapir Liu. PR and bug reports are welcome and can be submitted to the issue list. Please follow @zigo_101 (reachable from the left QR code) to get the latest news of Golds. |