Overview

Package rsa implements RSA encryption as specified in PKCS#1.

RSA is a single, fundamental operation that is used in this package to implement
either public-key encryption or public-key signatures.

The original specification for encryption and signatures with RSA is PKCS#1 and
the terms “RSA encryption” and “RSA signatures” by default refer to PKCS#1
version 1.5. However, that specification has flaws and new designs should use
version two, usually called by just OAEP and PSS, where possible.

Two sets of interfaces are included in this package. When a more abstract
interface isn’t necessary, there are functions for encrypting/decrypting with
v1.5/OAEP and signing/verifying with v1.5/PSS. If one needs to abstract over the
public-key primitive, the PrivateKey struct implements the Decrypter and Signer
interfaces from the crypto package.

The RSA operations in this package are not implemented using constant-time
algorithms.

Index

Package files

pss.go

Constants

Variables

  1. var ErrDecryption = errors.("crypto/rsa: decryption error")

ErrDecryption represents a failure to decrypt a message. It is deliberately
vague to avoid adaptive attacks.

  1. var ErrMessageTooLong = errors.("crypto/rsa: message too long for RSA public key size")

ErrMessageTooLong is returned when attempting to encrypt a message which is too
large for the size of the public key.

  1. var ErrVerification = errors.("crypto/rsa: verification error")

ErrVerification represents a failure to verify a signature. It is deliberately
vague to avoid adaptive attacks.

func DecryptOAEP

  1. func DecryptOAEP(hash hash., random io., priv *PrivateKey, ciphertext [], label []byte) ([], error)

OAEP is parameterised by a hash function that is used as a random oracle.
Encryption and decryption of a given message must use the same hash function and
sha256.New() is a reasonable choice.

The random parameter, if not nil, is used to blind the private-key operation and
avoid timing side-channel attacks. Blinding is purely internal to this function
– the random data need not match that used when encrypting.

The label parameter must match the value given when encrypting. See EncryptOAEP
for details.


Example:

  1. ciphertext, _ := hex.DecodeString("4d1ee10e8f286390258c51a5e80802844c3e6358ad6690b7285218a7c7ed7fc3a4c7b950fbd04d4b0239cc060dcc7065ca6f84c1756deb71ca5685cadbb82be025e16449b905c568a19c088a1abfad54bf7ecc67a7df39943ec511091a34c0f2348d04e058fcff4d55644de3cd1d580791d4524b92f3e91695582e6e340a1c50b6c6d78e80b4e42c5b4d45e479b492de42bbd39cc642ebb80226bb5200020d501b24a37bcc2ec7f34e596b4fd6b063de4858dbf5a4e3dd18e262eda0ec2d19dbd8e890d672b63d368768360b20c0b6b8592a438fa275e5fa7f60bef0dd39673fd3989cc54d2cb80c08fcd19dacbc265ee1c6014616b0e04ea0328c2a04e73460")
  2. label := []byte("orders")
  3. // crypto/rand.Reader is a good source of entropy for blinding the RSA
  4. // operation.
  5. rng := rand.Reader
  6. plaintext, err := DecryptOAEP(sha256.New(), rng, test2048Key, ciphertext, label)
  7. if err != nil {
  8. fmt.Fprintf(os.Stderr, "Error from decryption: %s\n", err)
  9. return
  10. }
  11. fmt.Printf("Plaintext: %s\n", string(plaintext))
  12. // Remember that encryption only provides confidentiality. The
  13. // ciphertext should be signed before authenticity is assumed and, even
  14. // then, consider that messages might be reordered.

func DecryptPKCS1v15

  1. func DecryptPKCS1v15(rand io., priv *PrivateKey, ciphertext []) ([]byte, )

DecryptPKCS1v15 decrypts a plaintext using RSA and the padding scheme from
PKCS#1 v1.5. If rand != nil, it uses RSA blinding to avoid timing side-channel
attacks.

Note that 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 DecryptPKCS1v15SessionKey for a
way of solving this problem.

  1. func DecryptPKCS1v15SessionKey(rand io., priv *PrivateKey, ciphertext [], key []byte)

DecryptPKCS1v15SessionKey decrypts a session key using RSA and the padding
scheme from PKCS#1 v1.5. If rand != nil, it uses RSA blinding to avoid timing
side-channel attacks. It 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. This will
remove any possibility that an attacker can learn any information about the
plaintext. See ``Chosen Ciphertext Attacks Against Protocols Based on the RSA
Encryption Standard PKCS #1’’, Daniel Bleichenbacher, Advances in Cryptology
(Crypto ‘98).

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 defeats the point of this function.
Using at least a 16-byte key will protect against this attack.


Example:

  1. // crypto/rand.Reader is a good source of entropy for blinding the RSA
  2. // operation.
  3. rng := rand.Reader
  4. // The hybrid scheme should use at least a 16-byte symmetric key. Here
  5. // we read the random key that will be used if the RSA decryption isn't
  6. // well-formed.
  7. key := make([]byte, 32)
  8. if _, err := io.ReadFull(rng, key); err != nil {
  9. panic("RNG failure")
  10. }
  11. rsaCiphertext, _ := hex.DecodeString("aabbccddeeff")
  12. if err := DecryptPKCS1v15SessionKey(rng, rsaPrivateKey, rsaCiphertext, key); err != nil {
  13. // can be determined without any secret information. (For
  14. // instance, if the length of key is impossible given the RSA
  15. // public key.)
  16. fmt.Fprintf(os.Stderr, "Error from RSA decryption: %s\n", err)
  17. }
  18. // Given the resulting key, a symmetric scheme can be used to decrypt a
  19. // larger ciphertext.
  20. block, err := aes.NewCipher(key)
  21. if err != nil {
  22. panic("aes.NewCipher failed: " + err.Error())
  23. }
  24. // Since the key is random, using a fixed nonce is acceptable as the
  25. // (key, nonce) pair will still be unique, as required.
  26. var zeroNonce [12]byte
  27. aead, err := cipher.NewGCM(block)
  28. if err != nil {
  29. panic("cipher.NewGCM failed: " + err.Error())
  30. }
  31. ciphertext, _ := hex.DecodeString("00112233445566")
  32. plaintext, err := aead.Open(nil, zeroNonce[:], ciphertext, nil)
  33. if err != nil {
  34. // The RSA ciphertext was badly formed; the decryption will
  35. // fail here because the AES-GCM key will be incorrect.
  36. fmt.Fprintf(os.Stderr, "Error decrypting: %s\n", err)
  37. return
  38. }
  39. fmt.Printf("Plaintext: %s\n", string(plaintext))

func

  1. func EncryptOAEP(hash .Hash, random .Reader, pub *, msg []byte, label []) ([]byte, )

EncryptOAEP encrypts the given message with RSA-OAEP.

OAEP is parameterised by a hash function that is used as a random oracle.
Encryption and decryption of a given message must use the same hash function and
sha256.New() is a reasonable choice.

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.

The label parameter may contain arbitrary data that will not be encrypted, but
which gives important context to the message. For example, if a given public key
is used to decrypt two types of messages then distinct label values could be
used to ensure that a ciphertext for one purpose cannot be used for another by
an attacker. If not required it can be empty.

The message must be no longer than the length of the public modulus minus twice
the hash length, minus a further 2.


Example:

  1. secretMessage := []byte("send reinforcements, we're going to advance")
  2. label := []byte("orders")
  3. // crypto/rand.Reader is a good source of entropy for randomizing the
  4. // encryption function.
  5. rng := rand.Reader
  6. ciphertext, err := EncryptOAEP(sha256.New(), rng, &test2048Key.PublicKey, secretMessage, label)
  7. if err != nil {
  8. fmt.Fprintf(os.Stderr, "Error from encryption: %s\n", err)
  9. return
  10. }
  11. // Since encryption is a randomized function, ciphertext will be
  12. // different each time.
  13. fmt.Printf("Ciphertext: %x\n", ciphertext)

func

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 rand parameter is used as a source of entropy to ensure that encrypting the
same message twice doesn’t result in the same ciphertext.

WARNING: use of this function to encrypt plaintexts other than session keys is
dangerous. Use RSA OAEP in new protocols.

func

  1. func SignPKCS1v15(rand .Reader, priv *, hash crypto., hashed []byte) ([], error)

SignPKCS1v15 calculates the signature of hashed using RSASSA-PKCS1-V1_5-SIGN
from RSA PKCS#1 v1.5. Note that hashed must be the result of hashing the input
message using the given hash function. If hash is zero, hashed is signed
directly. This isn’t advisable except for interoperability.

If rand is not nil then RSA blinding will be used to avoid timing side-channel
attacks.

This function is deterministic. Thus, if the set of possible messages is small,
an attacker may be able to build a map from messages to signatures and identify
the signed messages. As ever, signatures provide authenticity, not
confidentiality.


Example:

  1. // crypto/rand.Reader is a good source of entropy for blinding the RSA
  2. // operation.
  3. rng := rand.Reader
  4. message := []byte("message to be signed")
  5. // Only small messages can be signed directly; thus the hash of a
  6. // message, rather than the message itself, is signed. This requires
  7. // that the hash function be collision resistant. SHA-256 is the
  8. // least-strong hash function that should be used for this at the time
  9. // of writing (2016).
  10. hashed := sha256.Sum256(message)
  11. signature, err := SignPKCS1v15(rng, rsaPrivateKey, crypto.SHA256, hashed[:])
  12. if err != nil {
  13. fmt.Fprintf(os.Stderr, "Error from signing: %s\n", err)
  14. return
  15. }
  16. fmt.Printf("Signature: %x\n", signature)

func SignPSS

  1. func SignPSS(rand io., priv *PrivateKey, hash .Hash, hashed [], opts *PSSOptions) ([], error)

SignPSS calculates the signature of hashed using RSASSA-PSS [1]. Note that
hashed must be the result of hashing the input message using the given hash
function. The opts argument may be nil, in which case sensible defaults are
used.

func

  1. func VerifyPKCS1v15(pub *, hash crypto., hashed []byte, sig []) error

VerifyPKCS1v15 verifies an RSA PKCS#1 v1.5 signature. hashed is the result of
hashing the input message using the given hash function and sig is the
signature. A valid signature is indicated by returning a nil error. If hash is
zero then hashed is used directly. This isn’t advisable except for
interoperability.


Example:

  1. message := []byte("message to be signed")
  2. signature, _ := hex.DecodeString("ad2766728615cc7a746cc553916380ca7bfa4f8983b990913bc69eb0556539a350ff0f8fe65ddfd3ebe91fe1c299c2fac135bc8c61e26be44ee259f2f80c1530")
  3. // message, rather than the message itself, is signed. This requires
  4. // that the hash function be collision resistant. SHA-256 is the
  5. // least-strong hash function that should be used for this at the time
  6. // of writing (2016).
  7. hashed := sha256.Sum256(message)
  8. err := VerifyPKCS1v15(&rsaPrivateKey.PublicKey, crypto.SHA256, hashed[:], signature)
  9. if err != nil {
  10. fmt.Fprintf(os.Stderr, "Error from verification: %s\n", err)
  11. return
  12. }
  13. // signature is a valid signature of message from the public key.

func VerifyPSS

  1. func VerifyPSS(pub *PublicKey, hash .Hash, hashed [], sig []byte, opts *) error

VerifyPSS verifies a PSS signature. hashed is the result of hashing the input
message using the given hash function and sig is the signature. A valid
signature is indicated by returning a nil error. The opts argument may be nil,
in which case sensible defaults are used.

  1. type CRTValue struct {
  2. Exp *.Int // D mod (prime-1).
  3. Coeff *.Int // R·Coeff ≡ 1 mod Prime.
  4. R *.Int // product of primes prior to this (inc p and q).
  5. }

CRTValue contains the precomputed Chinese remainder theorem values.

type

  1. type OAEPOptions struct {
  2. // Hash is the hash function that will be used when generating the mask.
  3. Hash .Hash
  4. // Label is an arbitrary byte string that must be equal to the value
  5. // used when encrypting.
  6. Label []
  7. }

OAEPOptions is an interface for passing options to OAEP decryption using the
crypto.Decrypter interface.

type PKCS1v15DecryptOptions

  1. type PKCS1v15DecryptOptions struct {
  2. // SessionKeyLen is the length of the session key that is being
  3. // decrypted. If not zero, then a padding error during decryption will
  4. // cause a random plaintext of this length to be returned rather than
  5. // an error. These alternatives happen in constant time.
  6. SessionKeyLen int
  7. }

PKCS1v15DecrypterOpts is for passing options to PKCS#1 v1.5 decryption using the
crypto.Decrypter interface.

type

  1. type PSSOptions struct {
  2. // SaltLength controls the length of the salt used in the PSS
  3. // signature. It can either be a number of bytes, or one of the special
  4. // PSSSaltLength constants.
  5. SaltLength
  6.  
  7. // Hash, if not zero, overrides the hash function passed to SignPSS.
  8. // This is the only way to specify the hash function when using the
  9. // crypto.Signer interface.
  10. Hash crypto.
  11. }

PSSOptions contains options for creating and verifying PSS signatures.

func (*PSSOptions) HashFunc

HashFunc returns pssOpts.Hash so that PSSOptions implements crypto.SignerOpts.

type PrecomputedValues

  1. type PrecomputedValues struct {
  2. Dp, Dq *big. // D mod (P-1) (or mod Q-1)
  3. Qinv *big. // Q^-1 mod P
  4.  
  5. // CRTValues is used for the 3rd and subsequent primes. Due to a
  6. // historical accident, the CRT for the first two primes is handled
  7. // differently in PKCS#1 and interoperability is sufficiently
  8. // important that we mirror this.
  9. CRTValues []CRTValue
  10. }

type

  1. type PrivateKey struct {
  2. // public part.
  3. D *big. // private exponent
  4. Primes []*big. // prime factors of N, has >= 2 elements.
  5.  
  6. // Precomputed contains precomputed values that speed up private
  7. // operations, if available.
  8. Precomputed PrecomputedValues
  9. }

A PrivateKey represents an RSA key

  1. func GenerateKey(random .Reader, bits ) (*PrivateKey, )

GenerateKey generates an RSA keypair of the given bit size using the random
source random (for example, crypto/rand.Reader).

func GenerateMultiPrimeKey

  1. func GenerateMultiPrimeKey(random io., nprimes int, bits ) (*PrivateKey, )

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.

Table 1 in [2] suggests maximum numbers of primes for a given size.

[1] US patent 4405829 (1972, expired) [2]
http://www.cacr.math.uwaterloo.ca/techreports/2006/cacr2006-16.pdf

func (*PrivateKey)

  1. func (priv *) Decrypt(rand io., ciphertext []byte, opts .DecrypterOpts) (plaintext [], err error)

Decrypt decrypts ciphertext with priv. If opts is nil or of type
PKCS1v15DecryptOptions then PKCS#1 v1.5 decryption is performed. Otherwise opts
must have type
OAEPOptions and OAEP decryption is done.

  1. func (priv *) Precompute()

Precompute performs some calculations that speed up private key operations in
the future.

func (*PrivateKey) Public

  1. func (priv *PrivateKey) Public() .PublicKey

Public returns the public key corresponding to priv.

func (*PrivateKey)

  1. func (priv *) Sign(rand io., digest []byte, opts .SignerOpts) ([], error)

Sign signs digest with priv, reading randomness from rand. If opts is a
*PSSOptions then the PSS algorithm will be used, otherwise PKCS#1 v1.5 will be
used.

This method implements crypto.Signer, which is an interface to support keys
where the private part is kept in, for example, a hardware module. Common uses
should use the Sign* functions in this package directly.

  1. func (priv *) Validate() error

Validate performs basic sanity checks on the key. It returns nil if the key is
valid, or else an error describing a problem.

type

  1. type PublicKey struct {
  2. N *.Int // modulus
  3. E // public exponent
  4. }

A PublicKey represents the public part of an RSA key.