RFC 3447
Public-Key Cryptography Standards (PKCS) #1: RSA Cryptography Specifications Version 2.1
RFC 3447 ๐ Public-Key Cryptography Standards (PKCS) #1: RSA Cryptography Specifications Version 2.1
okay bestie, this one is the RSA Cryptography Specifications Version 2.1 ๐โจ It's from the Network Working Group, written by J. Jonsson and B. Kaliski of RSA Laboratories, and it's dated February 2003 ๐ . It's Informational (not a standard, just here to share info with the internet community), and it obsoletes RFC 2437 ๐ There's no Updates line in the header, so it doesn't update anything else.
Status of This Memo ๐
this memo is informational only ๐ธ It gives info to the Internet community and does not specify an Internet standard of any kind. distribution is unlimited, so share it with everyone ๐
Copyright Notice ยฉ๏ธ
the copyright is held by the Internet Society, and the exact notice is:
Copyright (C) The Internet Society (2003). All Rights Reserved.
Abstract ๐ง
so this memo is basically a republication of PKCS #1 v2.1 from RSA Laboratories' Public-Key Cryptography Standards (PKCS) series ๐ change control stays inside the PKCS process, and the body of this document comes straight from the PKCS #1 v2.1 document, with a few corrections made during the publication process ๐ซถ
Table of Contents ๐
1. Introduction...............................................2
2. Notation...................................................3
3. Key types..................................................6
3.1 RSA public key..........................................6
3.2 RSA private key.........................................7
4. Data conversion primitives.................................8
4.1 I2OSP...................................................9
4.2 OS2IP...................................................9
5. Cryptographic primitives..................................10
5.1 Encryption and decryption primitives...................10
5.2 Signature and verification primitives..................12
6. Overview of schemes.......................................14
7. Encryption schemes........................................15
7.1 RSAES-OAEP.............................................16
7.2 RSAES-PKCS1-v1_5.......................................23
8. Signature schemes with appendix...........................27
8.1 RSASSA-PSS.............................................29
8.2 RSASSA-PKCS1-v1_5......................................32
9. Encoding methods for signatures with appendix.............35
9.1 EMSA-PSS...............................................36
9.2 EMSA-PKCS1-v1_5........................................41
Appendix A. ASN.1 syntax...........................................44
A.1 RSA key representation.................................44
A.2 Scheme identification..................................46
Appendix B. Supporting techniques..................................52
B.1 Hash functions.........................................52
B.2 Mask generation functions..............................54
Appendix C. ASN.1 module...........................................56
Appendix D. Intellectual Property Considerations...................63
Appendix E. Revision history.......................................64
Appendix F. References.............................................65
Appendix G. About PKCS.............................................70
Appendix H. Corrections Made During RFC Publication Process........70
Security Considerations............................................70
Acknowledgements...................................................71
Authors' Addresses.................................................71
Full Copyright Statement...........................................72
1. Introduction ๐ฆ
okay so this doc gives recommendations for implementing public-key cryptography based on the RSA algorithm [42] โจ it covers these aspects:
- Cryptographic primitives
- Encryption schemes
- Signature schemes with appendix
- ASN.1 syntax for representing keys and for identifying the schemes
these recommendations are meant for general use in computer and communications systems, so they've got a fair amount of flexibility ๐ท application standards built on top of them may add extra constraints. the recommendations are meant to be compatible with the standard IEEE-1363-2000 [26], plus draft standards being developed by the ANSI X9F1 [1] and IEEE P1363 [27] working groups ๐
this document replaces PKCS #1 version 2.0 [35][44], but it keeps compatible techniques, so nothing gets left behind ๐ซถ
here's how the doc is laid out:
- Section 1 is the introduction.
- Section 2 defines some notation used in this document.
- Section 3 defines the RSA public and private key types.
- Sections 4 and 5 define several primitives, which are basic mathematical operations. Data conversion primitives are in Section 4, and cryptographic primitives (encryption-decryption, signature-verification) are in Section 5.
- Sections 6, 7, and 8 deal with the encryption and signature schemes in this document. Section 6 gives an overview. Along with the methods found in PKCS #1 v1.5, Section 7 defines an OAEP-based [3] encryption scheme, and Section 8 defines a PSS-based [4][5] signature scheme with appendix.
- Section 9 defines the encoding methods for the signature schemes in Section 8.
- Appendix A defines the ASN.1 syntax for the keys defined in Section 3 and the schemes in Sections 7 and 8.
- Appendix B defines the hash functions and the mask generation function used in this document, including ASN.1 syntax for the techniques.
- Appendix C gives an ASN.1 module.
- Appendices D, E, F and G cover intellectual property issues, outline the revision history of PKCS #1, give references to other publications and standards, and provide general information about the Public-Key Cryptography Standards.
2. Notation ๐ธ
this section is the symbol cheat sheet, so screenshot it ๐ธ here's what each symbol means:
cciphertext representative, an integer between 0 and n-1Cciphertext, an octet stringdRSA private exponentd_iadditional factor r_i's CRT exponent, a positive integer such that
e * d_i == 1 (mod (r_i-1)), i = 3, ..., u
dPp's CRT exponent, a positive integer such that
e * dP == 1 (mod (p-1))
dQq's CRT exponent, a positive integer such that
e * dQ == 1 (mod (q-1))
eRSA public exponentEMencoded message, an octet stringemBits(intended) length in bits of an encoded message EMemLen(intended) length in octets of an encoded message EMGCD(. , .)greatest common divisor of two nonnegative integersHashhash functionhLenoutput length in octets of hash function Hashklength in octets of the RSA modulus nKRSA private keyLoptional RSAES-OAEP label, an octet stringLCM(., ..., .)least common multiple of a list of nonnegative integersmmessage representative, an integer between 0 and n-1Mmessage, an octet stringmaskMGF output, an octet stringmaskLen(intended) length of the octet string maskMGFmask generation functionmgfSeedseed from which mask is generated, an octet stringmLenlength in octets of a message MnRSA modulus, n = r_1 * r_2 * ... * r_u , u >= 2(n, e)RSA public keyp, qfirst two prime factors of the RSA modulus nqInvCRT coefficient, a positive integer less than p such that
q * qInv == 1 (mod p)
r_iprime factors of the RSA modulus n, including r_1 = p, r_2 = q, and additional factors if anyssignature representative, an integer between 0 and n-1Ssignature, an octet stringsLenlength in octets of the EMSA-PSS saltt_iadditional prime factor r_i's CRT coefficient, a positive integer less than r_i such that
r_1 * r_2 * ... * r_(i-1) * t_i == 1 (mod r_i) ,
i = 3, ... , u
unumber of prime factors of the RSA modulus, u >= 2xa nonnegative integerXan octet string corresponding to xxLen(intended) length of the octet string X0xindicator of hexadecimal representation of an octet or an octet string; "0x48" denotes the octet with hexadecimal value 48; "(0x)48 09 0e" denotes the string of three consecutive octets with hexadecimal value 48, 09, and 0e, respectively\lambda(n)LCM(r_1-1, r_2-1, ... , r_u-1)\xorbit-wise exclusive-or of two octet strings\ceil(.)ceiling function; \ceil(x) is the smallest integer larger than or equal to the real number x||concatenation operator==congruence symbol; a == b (mod n) means that the integer n divides the integer a - b
Note. the CRT can be applied in a non-recursive way or a recursive way ๐ง this document uses a recursive approach following Garner's algorithm [22]. see also Note 1 in Section 3.2 โจ
3. Key types ๐
two key types get used in the primitives and schemes here: the RSA public key and the RSA private key ๐ together, a public key and a private key form an RSA key pair.
this spec supports so-called "multi-prime" RSA, where the modulus can have more than two prime factors ๐ the benefit is lower computational cost for the decryption and signature primitives, as long as the CRT (Chinese Remainder Theorem) is used. it runs better on single-processor platforms, but the gains are bigger on multiprocessor platforms, where the modular exponentiations can run in parallel ๐
if you want to know how multi-prime affects the security of the RSA cryptosystem, check out [49] ๐ง
3.1 RSA public key ๐ซง
for this document, an RSA public key has two components:
nthe RSA modulus, a positive integerethe RSA public exponent, a positive integer
in a valid RSA public key, the RSA modulus n is a product of u distinct odd primes r_i, i = 1, 2, ..., u, where u >= 2 ๐ฅ the RSA public exponent e is an integer between 3 and n - 1 that satisfies GCD(e, \lambda(n)) = 1, where \lambda(n) = LCM(r_1 - 1, ..., r_u - 1). by convention, the first two primes r_1 and r_2 can also be called p and q, respectively ๐
a recommended syntax for swapping RSA public keys between implementations is in Appendix A.1.1, but an implementation's internal representation can be different ๐
3.2 RSA private key โจ
okay so an RSA private key can come in two flavours for this doc, and I'm obsessed with how they're built ๐
- The first representation is the pair (n, d). Here's what the bits mean:
n the RSA modulus, a positive integer
d the RSA private exponent, a positive integer
- The second representation is a quintuple (p, q, dP, dQ, qInv) plus a (possibly empty) list of triplets (r_i, d_i, t_i), with i = 3, ..., u, one triplet for each prime that isn't in the quintuple. Here's the breakdown:
p the first factor, a positive integer
q the second factor, a positive integer
dP the first factor's CRT exponent, a positive integer
dQ the second factor's CRT exponent, a positive integer
qInv the (first) CRT coefficient, a positive integer
r_i the i-th factor, a positive integer
d_i the i-th factor's CRT exponent, a positive integer
t_i the i-th factor's CRT coefficient, a positive integer
Now for what makes a key valid ๐ฅ. With the first representation, the modulus n is the same as in the matching RSA public key, and it's the product of u distinct odd primes r_i (i = 1, 2, ..., u), where u >= 2. The private exponent d is a positive integer smaller than n that satisfies:
e * d == 1 (mod \lambda(n))
Here e is the matching RSA public exponent, and \lambda(n) is defined back in Section 3.1 ๐ฆ
With the second representation, p and q are the first two prime factors of n (aka r_1 and r_2). The CRT exponents dP and dQ are positive integers smaller than p and q respectively, and they satisfy:
e * dP == 1 (mod (p-1))
e * dQ == 1 (mod (q-1))
The CRT coefficient qInv is a positive integer smaller than p, and it satisfies:
q * qInv == 1 (mod p).
If u > 2, the representation has one or more triplets (r_i, d_i, t_i) for i = 3, ..., u. The r_i values are the extra prime factors of n. Each CRT exponent d_i (for i = 3, ..., u) satisfies:
e * d_i == 1 (mod (r_i - 1)).
Each CRT coefficient t_i (for i = 3, ..., u) is a positive integer smaller than r_i, and it satisfies:
R_i * t_i == 1 (mod r_i) ,
where R_i = r_1 * r_2 * ... * r_(i-1).
If you want to swap RSA private keys between implementations (including bits from both representations), there's a recommended syntax in Appendix A.1.2. An implementation's internal storage can look totally different though, so don't stress ๐ธ
Notes.
- The CRT coefficient definitions here, plus the formulas that use them in the Section 5 primitives, mostly follow Garner's algorithm [22] (see also Algorithm 14.71 in [37]). BUT, for compatibility with the RSA private key representations in PKCS #1 v2.0 and earlier versions, p and q have their roles flipped compared to the other primes. So the first CRT coefficient, qInv, is defined as the inverse of q mod p, not as the inverse of R_1 mod r_2 (which is the inverse of p mod q). Plot twist ๐
- Quisquater and Couvreur [40] noticed the perks of using the Chinese Remainder Theorem for RSA operations. Iconic of them ๐
4. Data conversion primitives โจ
Two data conversion primitives show up in the schemes this document defines:
- I2OSP - Integer-to-Octet-String primitive
- OS2IP - Octet-String-to-Integer primitive
For this doc, and matching ASN.1 syntax, an octet string is an ordered sequence of octets (eight-bit bytes). It's indexed from first (conventionally the leftmost) to last (the rightmost). When converting to and from integers, the first octet counts as the most significant one in these conversion primitives ๐ง
4.1 I2OSP
I2OSP turns a nonnegative integer into an octet string of a specified length. Here's the signature:
I2OSP (x, xLen)
Input:
x nonnegative integer to be converted
xLen intended length of the resulting octet string
Output:
X corresponding octet string of length xLen
Error: "integer too large"
Steps:
- If
x >= 256^xLen, output "integer too large" and stop. Too big bestie, can't fit ๐ โโ๏ธ - Write the integer x in its unique xLen-digit representation in base 256:
x = x_(xLen-1) 256^(xLen-1) + x_(xLen-2) 256^(xLen-2) + ...
+ x_1 256 + x_0,
where 0 <= x_i < 256. (Heads up: one or more leading digits will be zero if x is less than 256^(xLen-1).) ๐
- Let the octet X_i have the integer value x_(xLen-i) for 1 <= i <= xLen. Then output the octet string:
X = X_1 X_2 ... X_xLen.
4.2 OS2IP
OS2IP turns an octet string into a nonnegative integer. Signature time:
OS2IP (X)
Input:
X octet string to be converted
Output:
x corresponding nonnegative integer
Steps:
- Let X_1 X_2 ... X_xLen be the octets of X from first to last, and let x_(xLen-i) be the integer value of the octet X_i for 1 <= i <= xLen.
- Let:
x = x_(xLen-1) 256^(xLen-1) + x_(xLen-2) 256^(xLen-2) + ...
+ x_1 256 + x_0.
- Output x. Ta-da ๐
5. Cryptographic primitives โจ
Cryptographic primitives are the basic maths operations that cryptographic schemes get built on. They're meant to be implemented in hardware or as software modules, and they don't give you any security by themselves. The security comes from the scheme they sit inside ๐ฆ
This document specifies four primitives, grouped into two pairs: encryption and decryption, and signature and verification.
The primitive specs assume the inputs already meet certain conditions, most importantly that the RSA public and private keys are valid. Keep that in mind ๐
5.1 Encryption and decryption primitives
An encryption primitive turns a message representative into a ciphertext representative, controlled by a public key. A decryption primitive takes the ciphertext representative and recovers the message representative, controlled by the matching private key ๐
This document has one pair of encryption and decryption primitives, used by its encryption schemes, and it's specified right here: RSAEP/RSADP. RSAEP and RSADP do the same maths operation, just with different keys going in.
These primitives are the same as IFEP-RSA/IFDP-RSA in IEEE Std 1363-2000 [26] (with multi-prime RSA support added), and they're compatible with PKCS #1 v1.5.
The main operation in each primitive is exponentiation.
5.1.1 RSAEP
RSAEP ((n, e), m)
Input:
(n, e) RSA public key
m message representative, an integer between 0 and n - 1
Output:
c ciphertext representative, an integer between 0 and n - 1
Error: "message representative out of range"
Assumption: RSA public key (n, e) is valid
Steps:
- If the message representative m is not between 0 and n - 1, output "message representative out of range" and stop. Out of range is a vibe-killer ๐
- Let
c = m^e mod n. - Output c. โจ
5.1.2 RSADP
RSADP (K, c)
Input:
K RSA private key, where K has one of the following forms:
- a pair (n, d)
- a quintuple (p, q, dP, dQ, qInv) and a possibly empty
sequence of triplets (r_i, d_i, t_i), i = 3, ..., u
c ciphertext representative, an integer between 0 and n - 1
Output:
m message representative, an integer between 0 and n - 1
Error: "ciphertext representative out of range"
Assumption: RSA private key K is valid
Steps:
- If the ciphertext representative c is not between 0 and n - 1, output "ciphertext representative out of range" and stop.
- Compute the message representative m like this:
a. If the first form (n, d) of K is used, let m = c^d mod n.
b. If the second form (p, q, dP, dQ, qInv) and (r_i, d_i, t_i) of K is used, do the following:
i. Let m_1 = c^dP mod p and m_2 = c^dQ mod q.
ii. If u > 2, let m_i = c^(d_i) mod r_i, for i = 3, ..., u.
iii. Let h = (m_1 - m_2) * qInv mod p.
iv. Let m = m_2 + q * h.
v. If u > 2, let R = r_1 and for i = 3 to u do:
- Let
R = R * r_(i-1). - Let
h = (m_i - m) * t_i mod r_i. - Let
m = m + R * h.
- Output m. ๐
Note. Step 2.b can be rewritten as one single loop, as long as you reverse the order of p and q. For consistency with PKCS #1 v2.0 though, the first two primes p and q get handled separately from the additional primes. Consistency is bestie behaviour ๐ซถ
5.2 Signature and verification primitives
A signature primitive turns a message representative into a signature representative, controlled by a private key. A verification primitive recovers the message representative from the signature representative, controlled by the matching public key โ๏ธ
This document has one pair of signature and verification primitives, used by its signature schemes, and it's specified here: RSASP1/RSAVP1.
These primitives are the same as IFSP-RSA1/IFVP-RSA1 in IEEE 1363-2000 [26] (with multi-prime RSA support added), and they're compatible with PKCS #1 v1.5.
The main operation in each primitive is exponentiation, same as the encryption and decryption primitives in Section 5.1. RSASP1 and RSAVP1 are exactly the same as RSADP and RSAEP, except their input and output argument names are different. They're kept separate because they're meant for different purposes ๐
5.2.1 RSASP1
RSASP1 (K, m)
Input:
K RSA private key, where K has one of the following forms:
- a pair (n, d)
- a quintuple (p, q, dP, dQ, qInv) and a (possibly empty)
sequence of triplets (r_i, d_i, t_i), i = 3, ..., u
m message representative, an integer between 0 and n - 1
Output:
s signature representative, an integer between 0 and n - 1
Error: "message representative out of range"
Assumption: RSA private key K is valid
Steps:
- If the message representative m is not between 0 and n - 1, output "message representative out of range" and stop.
- Compute the signature representative s like this:
a. If the first form (n, d) of K is used, let s = m^d mod n.
b. If the second form (p, q, dP, dQ, qInv) and (r_i, d_i, t_i) of K is used, do the following:
i. Let s_1 = m^dP mod p and s_2 = m^dQ mod q.
ii. If u > 2, let s_i = m^(d_i) mod r_i, for i = 3, ..., u.
iii. Let h = (s_1 - s_2) * qInv mod p.
iv. Let s = s_2 + q * h.
v. If u > 2, let R = r_1 and for i = 3 to u do:
- Let
R = R * r_(i-1). - Let
h = (s_i - s) * t_i mod r_i. - Let
s = s + R * h.
- Output s. ๐ฆ
Note. Step 2.b can be rewritten as one single loop, as long as you reverse the order of p and q. For consistency with PKCS #1 v2.0 though, the first two primes p and q get handled separately from the additional primes.
5.2.2 RSAVP1
RSAVP1 ((n, e), s)
Input:
(n, e) RSA public key
s signature representative, an integer between 0 and n - 1
Output:
m message representative, an integer between 0 and n - 1
Error: "signature representative out of range"
Assumption: RSA public key (n, e) is valid
Steps:
- If the signature representative s is not between 0 and n - 1, output "signature representative out of range" and stop.
- Let
m = s^e mod n. - Output m. ๐
6. Overview of schemes โจ
okay so a scheme is basically when you mix cryptographic primitives and other techniques together to hit one specific security goal ๐๐ this doc defines two kinds: encryption schemes and signature schemes with appendix ๐
the schemes here are kinda minimal, bestie. all they do is process data with an RSA public or private key. they do NOT cover getting or validating the key ๐ so in real life an app will also need its own key management stuff to pick which RSA keys to use for a scheme operation. those extra details are totally outside this doc ๐ธ
same as with the primitives in Section 5, the scheme specs assume the inputs are good, especially that the RSA public and private keys are valid โ if a key is invalid, the behavior of an implementation is unspecified ๐ and how bad that is depends on the app. some ways to handle key validation: the app checks explicitly, the public-key infrastructure checks it, or whoever generated the key takes the blame for anything done with a bad key ๐ญ
a generally good crypto practice is to use a given RSA key pair in only one scheme ๐ฅ this avoids the risk that a weakness in one scheme ruins the security of another, and it may be essential for provable security too ๐ RSAES-PKCS1-v1_5 (Section 7.2) and RSASSA-PKCS1-v1_5 (Section 8.2) have traditionally been used together with no known bad interactions (this is literally the model PKCS #1 v1.5 introduced ๐ง), but using one key pair for both like that is not recommended for new applications ๐ซถ
let's make this super clear: reusing one key pair across schemes is the thing to avoid ๐ค
here's the risk in action ๐ฆ say a key pair is used in both RSAES-OAEP (Section 7.1) and RSAES-PKCS1-v1_5. RSAES-OAEP alone would hold up against attacks, but an opponent could exploit a weakness in the RSAES-PKCS1-v1_5 implementation and recover messages encrypted with either scheme ๐ another one: say a key pair is used in both RSASSA-PSS (Section 8.1) and RSASSA-PKCS1-v1_5. then the security proof for RSASSA-PSS isn't enough anymore, because the proof doesn't account for signatures being made with a second scheme ๐ญ similar concerns may apply if a key pair is shared between one of the schemes defined here and a variant defined somewhere else ๐
7. Encryption schemes ๐
okay bestie, for this doc an encryption scheme is made of an encryption operation and a decryption operation ๐ the encryption operation turns a message into a ciphertext using the recipient's RSA public key, and the decryption operation gets the message back from the ciphertext using the recipient's matching RSA private key ๐
encryption schemes show up in all kinds of apps ๐ท a super typical one is a key establishment protocol, where the message carries key material that needs to get from one party to another confidentially ๐คซ for example, PKCS #7 [45] uses this kind of protocol to send a content-encryption key from a sender to a recipient, and the encryption schemes here would be suitable key-encryption algorithms in that setup ๐
this doc specifies two encryption schemes: RSAES-OAEP and RSAES-PKCS1-v1_5 ๐ RSAES-OAEP is recommended for new applications โจ RSAES-PKCS1-v1_5 is only included for compatibility with existing applications, and is not recommended for new applications ๐ฅบ
the encryption schemes follow a general model similar to the one in IEEE Std 1363-2000 [26] ๐งฉ they combine encryption and decryption primitives with an encoding method for encryption. so for encryption, the operations apply a message encoding operation to the message to get an encoded message, which then gets converted into an integer message representative ๐ข an encryption primitive is applied to that representative to produce the ciphertext โจ going the other way, the decryption operations apply a decryption primitive to the ciphertext to recover a message representative, which then gets converted into an octet string encoded message ๐ฆ then a message decoding operation is applied to the encoded message to recover the message and check that the decryption was correct ๐
one more thing, and it's a big one ๐ to avoid implementation weaknesses in how errors are handled inside the decoding operation (see [6] and [36]), the encoding and decoding operations for RSAES-OAEP and RSAES-PKCS1-v1_5 are baked right into the specs of their respective encryption schemes instead of being defined in separate specs ๐ and both encryption schemes are compatible with the matching schemes in PKCS #1 v2.0 ๐
7.1 RSAES-OAEP
Okay bestie, RSAES-OAEP is the glow-up ๐ It combines the RSAEP and RSADP primitives (Sections 5.1.1 and 5.1.2) with the EME-OAEP encoding method (step 1.b in Section 7.1.1 and step 3 in Section 7.1.2). EME-OAEP is based on Bellare and Rogaway's Optimal Asymmetric Encryption scheme [3]. (OAEP stands for "Optimal Asymmetric Encryption Padding.") It's also compatible with the IFES scheme from IEEE Std 1363-2000 [26], where the encryption and decryption primitives are IFEP-RSA and IFDP-RSA and the message encoding method is EME-OAEP โจ. RSAES-OAEP can handle messages up to k - 2hLen - 2 octets, where hLen is the length of the output from the underlying hash function and k is the length in octets of the recipient's RSA modulus ๐.
Assuming that computing e-th roots modulo n is infeasible and the mask generation function in RSAES-OAEP has appropriate properties, RSAES-OAEP is semantically secure against adaptive chosen-ciphertext attacks ๐ฅ This assurance is provable, meaning the difficulty of breaking RSAES-OAEP can be directly related to the difficulty of inverting the RSA function, as long as the mask generation function is treated as a black box or random oracle. See [21] and the note below for more tea on that.
Both the encryption and decryption operations of RSAES-OAEP take a label L as input. In this version of PKCS #1, L is the empty string ๐ธ Other uses of the label are outside the scope of this document. See Appendix A.2.1 for the relevant ASN.1 syntax.
RSAES-OAEP is parameterized by the choice of hash function and mask generation function. That choice should be fixed for a given RSA key ๐ Suggested hash and mask generation functions are given in Appendix B.
Note. Recent results have clarified the security properties of the OAEP encoding method [3] (roughly the procedure in step 1.b of Section 7.1.1), and it's giving clarity ๐ง Here's the backstory. In 1994, Bellare and Rogaway [3] introduced a security concept they called plaintext awareness (PA94). They proved that if a deterministic public-key encryption primitive (e.g., RSAEP) is hard to invert without the private key, then the corresponding OAEP-based encryption scheme is plaintext-aware (in the random oracle model). Roughly, that means an adversary can't produce a valid ciphertext without actually "knowing" the underlying plaintext. Plaintext awareness is closely related to how well a scheme resists chosen-ciphertext attacks. In those attacks, an adversary gets to send queries to an oracle that simulates the decryption primitive, and then uses the results to try to decrypt a challenge ciphertext ๐
However, there are two flavors of chosen-ciphertext attacks, and PA94 only implies security against one of them ๐ The difference is what the adversary is allowed to do after receiving the challenge ciphertext. The indifferent attack scenario (denoted CCA1) doesn't allow any queries to the decryption oracle after the adversary gets the challenge ciphertext. The adaptive scenario (denoted CCA2) does allow them, except the decryption oracle refuses to decrypt the challenge ciphertext once it's published. In 1998, Bellare and Rogaway, together with Desai and Pointcheval [2], came up with a new, stronger notion of plaintext awareness (PA98) that does imply security against CCA2 โจ
To sum up, there are two possible sources of confusion: thinking PA94 and PA98 are equivalent, or thinking CCA1 and CCA2 are equivalent. Either assumption leads to the conclusion that the Bellare-Rogaway paper implies security of OAEP against CCA2, and it doesn't ๐
(Footnote: It might be fair to mention that PKCS #1 v2.0 cites [3] and claims that "a chosen ciphertext attack is ineffective against a plaintext-aware encryption scheme such as RSAES-OAEP" without specifying the kind of plaintext awareness or chosen ciphertext attack considered.)
OAEP has never been proven secure against CCA2. In fact, Victor Shoup [48] has demonstrated that such a proof doesn't exist in the general case ๐ญ Put simply, Shoup showed that an adversary in the CCA2 scenario who knows how to partially invert the encryption primitive, but not how to invert it completely, may well be able to break the scheme. For example, you can imagine an attacker who can break RSAES-OAEP if she knows how to recover all but the first 20 bytes of a random integer encrypted with RSAEP. That attacker doesn't need to fully invert RSAEP, because she doesn't use the first 20 octets in her attack.
Still, RSAES-OAEP is secure against CCA2, which was proved by Fujisaki, Okamoto, Pointcheval, and Stern [21] shortly after Shoup's result was announced ๐ฆ Using clever lattice reduction techniques, they showed how to invert RSAEP completely given a sufficiently large part of the pre-image. This observation, combined with a proof that OAEP is secure against CCA2 if the underlying encryption primitive is hard to partially invert, fills the gap between what Bellack and Rogaway proved about RSAES-OAEP and what some people may have believed they proved. Somewhat paradoxically, we're saved by an ostensible weakness in RSAEP (i.e., the whole inverse can be deduced from parts of it) ๐
Unfortunately, the security reduction isn't efficient for concrete parameters. The proof successfully relates an adversary Adv against the CCA2 security of RSAES-OAEP to an algorithm Inv that inverts RSA, but the probability of success for Inv is only approximately \epsilon^2 / 2^18, where \epsilon is the probability of success for Adv.
(Footnote: In [21] the probability of success for the inverter was \epsilon^2 / 4. The additional factor 1 / 2^16 is due to the eight fixed zero bits at the beginning of the encoded message EM, which aren't present in the variant of OAEP considered in [21] (Inv must apply Adv twice to invert RSA, and each application corresponds to a factor 1 / 2^8).)
On top of that, the running time for Inv is approximately t^2, where t is the running time of the adversary. So we can't rule out that attacking RSAES-OAEP is considerably easier than inverting RSA for concrete parameters ๐ฌ Still, the existence of a security proof gives some assurance that the RSAES-OAEP construction is sounder than ad hoc constructions such as RSAES-PKCS1-v1_5 ๐
Heads up: the security reduction is loose for concrete parameters, so the proof alone doesn't guarantee that attacking RSAES-OAEP is as hard as inverting RSA.
Hybrid encryption schemes based on the RSA-KEM key encapsulation paradigm offer tight proofs of security that apply directly to concrete parameters. See [30] for discussion. Future versions of PKCS #1 may specify schemes based on this paradigm ๐
7.1.1 Encryption operation
Here's the big-picture function signature for encryption ๐
RSAES-OAEP-ENCRYPT ((n, e), M, L)
Options:
Hash: hash function (hLen denotes the length in octets of the hash function output)MGF: mask generation function
Input:
(n, e): recipient's RSA public key (k denotes the length in octets of the RSA modulus n)M: message to be encrypted, an octet string of length mLen, where mLen <= k - 2hLen - 2L: optional label to be associated with the message; the default value for L, if L is not provided, is the empty string
Output:
C: ciphertext, an octet string of length k
Errors:
"message too long""label too long"
Assumption: RSA public key (n, e) is valid ๐ซถ
Steps:
- Length checking:
- a. If the length of L is greater than the input limitation for the hash function (
2^61 - 1octets for SHA-1), output"label too long"and stop. - b. If mLen > k - 2hLen - 2, output
"message too long"and stop.
- a. If the length of L is greater than the input limitation for the hash function (
- EME-OAEP encoding (see Figure 1 below) ๐
- a. If the label L is not provided, let L be the empty string. Let
lHash = Hash(L), an octet string of length hLen (see the note below). - b. Generate an octet string PS consisting of
k - mLen - 2hLen - 2zero octets. The length of PS may be zero. - c. Concatenate lHash, PS, a single octet with hexadecimal value
0x01, and the message M to form a data block DB of lengthk - hLen - 1octets as:
- a. If the label L is not provided, let L be the empty string. Let
DB = lHash || PS || 0x01 || M.
- d. Generate a random octet string seed of length hLen.
- e. Let
dbMask = MGF(seed, k - hLen - 1). - f. Let
maskedDB = DB \xor dbMask. - g. Let
seedMask = MGF(maskedDB, hLen). - h. Let
maskedSeed = seed \xor seedMask. - i. Concatenate a single octet with hexadecimal value
0x00, maskedSeed, and maskedDB to form an encoded message EM of length k octets as:
EM = 0x00 || maskedSeed || maskedDB.
- RSA encryption ๐ฅ
- a. Convert the encoded message EM to an integer message representative m (see Section 4.2):
m = OS2IP (EM). - b. Apply the RSAEP encryption primitive (Section 5.1.1) to the RSA public key (n, e) and the message representative m to produce an integer ciphertext representative c:
c = RSAEP ((n, e), m). - c. Convert the ciphertext representative c to a ciphertext C of length k octets (see Section 4.1):
C = I2OSP (c, k).
- a. Convert the encoded message EM to an integer message representative m (see Section 4.2):
- Output the ciphertext C โจ
Note. If L is the empty string, the corresponding hash value lHash has the following hexadecimal representation for different choices of Hash ๐ธ
SHA-1: (0x)da39a3ee 5e6b4b0d 3255bfef 95601890 afd80709
SHA-256: (0x)e3b0c442 98fc1c14 9afbf4c8 996fb924 27ae41e4 649b934c
a495991b 7852b855
SHA-384: (0x)38b060a7 51ac9638 4cd9327e b1b1e36a 21fdb711 14be0743
4c0cc7bf 63f6e1da 274edebf e76f65fb d51ad2f1 4898b95b
SHA-512: (0x)cf83e135 7eefb8bd f1542850 d66d8007 d620e405 0b5715dc
83f4a921 d36ce9ce 47d0d13c 5d85f2b0 ff8318d2 877eec2f
63b931bd 47417a81 a538327a f927da3e
Here's the diagram, because pictures slap ๐ฆ
__________________________________________________________________
+----------+---------+-------+
DB = | lHash | PS | M |
+----------+---------+-------+
|
+----------+ V
| seed |--> MGF ---> xor
+----------+ |
| |
+--+ V |
|00| xor <----- MGF <-----|
+--+ | |
| | |
V V V
+--+----------+----------------------------+
EM = |00|maskedSeed| maskedDB |
+--+----------+----------------------------+
__________________________________________________________________
Figure 1: EME-OAEP encoding operation. lHash is the hash of the optional label L. Decoding operation follows reverse steps to recover M and verify lHash and PS. ๐
7.1.2. Decryption operation ๐โจ
okay bestie, this is the decryption side of RSAES-OAEP, and it's giving careful ๐ Here's the whole setup:
RSAES-OAEP-DECRYPT (K, C, L)
Options:
Hash hash function (hLen denotes the length in octets of the hash
function output)
MGF mask generation function
Input:
K recipient's RSA private key (k denotes the length in octets
of the RSA modulus n)
C ciphertext to be decrypted, an octet string of length k,
where k = 2hLen + 2
L optional label whose association with the message is to be
verified; the default value for L, if L is not provided, is
the empty string
Output:
M message, an octet string of length mLen, where mLen <= k -
2hLen - 2
Error: "decryption error"
Now the steps ๐ง
- Length checking:
- a. If the length of
Lis greater than the input limitation for the hash function (2^61 - 1octets for SHA-1), output "decryption error" and stop. - b. If the length of the ciphertext
Cis notkoctets, output "decryption error" and stop. - c. If
k < 2hLen + 2, output "decryption error" and stop.
- a. If the length of
- RSA decryption:
- a. Convert the ciphertext
Cto an integer ciphertext representativec(see Section 4.2):c = OS2IP (C). - b. Apply the RSADP decryption primitive (Section 5.1.2) to the RSA private key
Kand the ciphertext representativecto produce an integer message representativem:m = RSADP (K, c).If RSADP outputs "ciphertext representative out of range" (meaning thatc >= n), output "decryption error" and stop. - c. Convert the message representative
mto an encoded messageEMof lengthkoctets (see Section 4.1):EM = I2OSP (m, k).
- a. Convert the ciphertext
- EME-OAEP decoding:
- a. If the label
Lis not provided, letLbe the empty string. LetlHash = Hash(L), an octet string of lengthhLen(see the note in Section 7.1.1). - b. Separate the encoded message
EMinto a single octetY, an octet stringmaskedSeedof lengthhLen, and an octet stringmaskedDBof lengthk - hLen - 1asEM = Y || maskedSeed || maskedDB. - c. Let
seedMask = MGF(maskedDB, hLen). - d. Let
seed = maskedSeed \xor seedMask. - e. Let
dbMask = MGF(seed, k - hLen - 1). - f. Let
DB = maskedDB \xor dbMask. - g. Separate
DBinto an octet stringlHash'of lengthhLen, a (possibly empty) padding stringPSconsisting of octets with hexadecimal value0x00, and a messageMasDB = lHash' || PS || 0x01 || M.If there is no octet with hexadecimal value0x01to separatePSfromM, iflHashdoes not equallHash', or ifYis nonzero, output "decryption error" and stop. (See the note below.)
- a. If the label
- Output the message
M.
Note. Care must be taken to ensure that an opponent cannot distinguish the different error conditions in Step 3.g, whether by error message or timing, or, more generally, learn partial information about the encoded message EM. Otherwise an opponent may be able to obtain useful information about the decryption of the ciphertext C, leading to a chosen-ciphertext attack such as the one observed by Manger [36]. ๐ฑ
7.2. RSAES-PKCS1-v1_5 ๐ธ
RSAES-PKCS1-v1_5 mixes the RSAEP and RSADP primitives (Sections 5.1.1 and 5.1.2) with the EME-PKCS1-v1_5 encoding method (step 1 in Section 7.2.1 and step 3 in Section 7.2.2). It is mathematically equivalent to the encryption scheme in PKCS #1 v1.5. RSAES-PKCS1-v1_5 can handle messages of length up to k - 11 octets (k is the octet length of the RSA modulus), although care should be taken to avoid certain attacks on low-exponent RSA due to Coppersmith, Franklin, Patarin, and Reiter when long messages are encrypted (see the third bullet in the notes below and [10]; [14] contains an improved attack). As a general rule, the use of this scheme for encrypting an arbitrary message, as opposed to a randomly generated key, is not recommended. ๐
It's possible to generate valid RSAES-PKCS1-v1_5 ciphertexts without knowing the corresponding plaintexts, with a reasonable probability of success. This ability can be exploited in a chosen-ciphertext attack as shown in [6]. Therefore, if RSAES-PKCS1-v1_5 is to be used, certain easily implemented countermeasures should be taken to thwart the attack found in [6]. Typical examples include the addition of structure to the data to be encoded, rigorous checking of PKCS #1 v1.5 conformance (and other redundancy) in decrypted messages, and the consolidation of error messages in a client-server protocol based on PKCS #1 v1.5. These can all be effective countermeasures and do not involve changes to a PKCS #1 v1.5-based protocol. See [7] for a further discussion of these and other countermeasures. It has recently been shown that the security of the SSL/TLS handshake protocol [17], which uses RSAES-PKCS1-v1_5 and certain countermeasures, can be related to a variant of the RSA problem; see [32] for discussion. ๐
Note. The following passages describe some security recommendations pertaining to the use of RSAES-PKCS1-v1_5. Recommendations from version 1.5 of this document are included as well as new recommendations motivated by cryptanalytic advances made in the intervening years.
- It is recommended that the pseudorandom octets in step 2 in Section 7.2.1 be generated independently for each encryption process, especially if the same data is input to more than one encryption process. Haastad's results [24] are one motivation for this recommendation. ๐ฅ
- The padding string
PSin step 2 in Section 7.2.1 is at least eight octets long, which is a security condition for public-key operations that makes it difficult for an attacker to recover data by trying all possible encryption blocks. ๐ก๏ธ - The pseudorandom octets can also help thwart an attack due to Coppersmith et al. [10] (see [14] for an improvement of the attack) when the size of the message to be encrypted is kept small. The attack works on low-exponent RSA when similar messages are encrypted with the same RSA public key. More specifically, in one flavor of the attack, when two inputs to RSAEP agree on a large fraction of bits (8/9) and low-exponent RSA (
e = 3) is used to encrypt both of them, it may be possible to recover both inputs with the attack. Another flavor of the attack is successful in decrypting a single ciphertext when a large fraction (2/3) of the input to RSAEP is already known. For typical applications, the message to be encrypted is short (e.g., a 128-bit symmetric key) so not enough information will be known or common between two messages to enable the attack. However, if a long message is encrypted, or if part of a message is known, then the attack may be a concern. In any case, the RSAES-OAEP scheme overcomes the attack. ๐ง
7.2.1. Encryption operation โจ
RSAES-PKCS1-V1_5-ENCRYPT ((n, e), M)
Input: (n, e) recipient's RSA public key (k denotes the length in octets of the modulus n) M message to be encrypted, an octet string of length mLen, where mLen <= k - 11
Output: C ciphertext, an octet string of length k
Error: "message too long"
Steps:
- Length checking: If
mLen > k - 11, output "message too long" and stop. - EME-PKCS1-v1_5 encoding:
- a. Generate an octet string
PSof lengthk - mLen - 3consisting of pseudo-randomly generated nonzero octets. The length ofPSwill be at least eight octets. - b. Concatenate
PS, the messageM, and other padding to form an encoded messageEMof lengthkoctets asEM = 0x00 || 0x02 || PS || 0x00 || M.
- a. Generate an octet string
- RSA encryption:
- a. Convert the encoded message
EMto an integer message representativem(see Section 4.2):m = OS2IP (EM). - b. Apply the RSAEP encryption primitive (Section 5.1.1) to the RSA public key
(n, e)and the message representativemto produce an integer ciphertext representativec:c = RSAEP ((n, e), m). - c. Convert the ciphertext representative
cto a ciphertextCof lengthkoctets (see Section 4.1):C = I2OSP (c, k).
- a. Convert the encoded message
- Output the ciphertext
C.
7.2.2. Decryption operation ๐ฆ
RSAES-PKCS1-V1_5-DECRYPT (K, C)
Input: K recipient's RSA private key C ciphertext to be decrypted, an octet string of length k, where k is the length in octets of the RSA modulus n
Output: M message, an octet string of length at most k - 11
Error: "decryption error"
Steps:
- Length checking: If the length of the ciphertext
Cis notkoctets (or ifk < 11), output "decryption error" and stop. - RSA decryption:
- a. Convert the ciphertext
Cto an integer ciphertext representativec(see Section 4.2):c = OS2IP (C). - b. Apply the RSADP decryption primitive (Section 5.1.2) to the RSA private key
(n, d)and the ciphertext representativecto produce an integer message representativem:m = RSADP ((n, d), c).If RSADP outputs "ciphertext representative out of range" (meaning thatc >= n), output "decryption error" and stop. - c. Convert the message representative
mto an encoded messageEMof lengthkoctets (see Section 4.1):EM = I2OSP (m, k).
- a. Convert the ciphertext
- EME-PKCS1-v1_5 decoding: Separate the encoded message
EMinto an octet stringPSconsisting of nonzero octets and a messageMasEM = 0x00 || 0x02 || PS || 0x00 || M.If the first octet ofEMdoes not have hexadecimal value0x00, if the second octet ofEMdoes not have hexadecimal value0x02, if there is no octet with hexadecimal value0x00to separatePSfromM, or if the length ofPSis less than 8 octets, output "decryption error" and stop. (See the note below.) - Output
M.
Note. Care shall be taken to ensure that an opponent cannot distinguish the different error conditions in Step 3, whether by error message or timing. Otherwise an opponent may be able to obtain useful information about the decryption of the ciphertext C, leading to a strengthened version of Bleichenbacher's attack [6]; compare to Manger's attack [36]. ๐จ
8. Signature schemes with appendix โจ
okay so for this doc, a signature scheme with appendix is basically two operations: a signature generation operation that makes a signature from a message using the signer's RSA private key, and a signature verification operation that checks that signature against the message using the signer's matching RSA public key. ๐ To verify one of these, you need the actual message, which is what makes them different from the signature schemes with message recovery. Those ones aren't supported in this document, so we're skipping them ๐ โโ๏ธ
These appendix schemes are super versatile. For example, they'd be solid signature algorithms for X.509 certificates [28]. Related schemes could also be used in PKCS #7 [45], but the current PKCS #7 version keeps the hash function separate from the signature scheme, which is different from how this doc does it. Check the note in Appendix A.2.3 for the full tea โ
This document specifies two signature schemes with appendix: RSASSA-PSS and RSASSA-PKCS1-v1_5. No attacks are known against RSASSA-PKCS1-v1_5, but for extra robustness, RSASSA-PSS is recommended for eventual adoption in new applications. RSASSA-PKCS1-v1_5 is kept for compatibility with existing applications. It's still appropriate for new applications, but a gradual transition to RSASSA-PSS is encouraged ๐
The schemes here follow a general model similar to IEEE Std 1363-2000 [26]. They combine signature and verification primitives with an encoding method for signatures. Signature generation applies a message encoding operation to the message to get an encoded message, which then gets converted into an integer message representative. A signature primitive is applied to that representative to make the signature. Going the other way, signature verification applies a signature verification primitive to the signature to recover a message representative, which is then converted into an octet string encoded message. Then a verification operation checks the message and the encoded message to see whether they're consistent ๐งฉ
If the encoding method is deterministic (like EMSA-PKCS1-v1_5), the verification operation may apply the message encoding operation to the message and compare the result to the encoded message it already derived. If they match, the signature is considered valid โ If the method is randomized (like EMSA-PSS), verification is typically more complicated. For example, EMSA-PSS verification pulls the random salt and a hash output out of the encoded message, then checks that the hash output, the salt, and the message are consistent with each other. The hash output is a deterministic function of the message and the salt, so that's what it's checking against ๐ธ
For both signature schemes with appendix in this document, signature generation and signature verification are readily implemented as "single-pass" operations, as long as the signature is placed after the message. For an example format with RSASSA-PKCS1-v1_5, check PKCS #7 [45] ๐
8.1 RSASSA-PSS
RSASSA-PSS combines the RSASP1 and RSAVP1 primitives with the EMSA-PSS encoding method. ๐ฆ It's compatible with the IFSSA scheme as amended in the IEEE P1363a draft [27], where the signature and verification primitives are IFSP-RSA1 and IFVP-RSA1 as defined in IEEE Std 1363-2000 [26], and the message encoding method is EMSA4. EMSA4 is slightly more general than EMSA-PSS because it works on bit strings instead of octet strings. EMSA-PSS is equivalent to EMSA4 when the operands, plus the hash and salt values, are all octet strings.
How long a message RSASSA-PSS can handle is either unrestricted or limited by a very large number. It depends on the hash function underneath the EMSA-PSS encoding method ๐
Assuming that computing e-th roots modulo n is infeasible, and that the hash and mask generation functions in EMSA-PSS have the right properties, RSASSA-PSS gives you secure signatures ๐ This is provable. The difficulty of forging signatures can be directly tied to the difficulty of inverting the RSA function, as long as the hash and mask generation functions are treated as black boxes or random oracles. The bounds in the security proof are basically "tight," meaning the success probability and running time of the best forger against RSASSA-PSS are very close to the matching parameters for the best RSA inversion algorithm. See [4][13][31] for more on this ๐ค
Here's the tricky part. RSASSA-PKCS1-v1_5 embeds a hash function identifier in its encoded message, but EMSA-PSS doesn't. So in theory, an adversary could swap in a different (and potentially weaker) hash function than the one the signer picked ๐ฑ That's why it's recommended that the EMSA-PSS mask generation function be based on the same hash function. This way, the whole encoded message depends on the hash function, and it becomes hard for an opponent to substitute a different one than the signer intended. Matching hash functions only helps prevent hash function substitution. It isn't needed if that substitution is handled some other way, like the verifier accepting only one designated hash function. See [34] for more on all of this. The provable security of RSASSA-PSS doesn't depend on the hash function in the mask generation function being the same as the one applied to the message โจ
RSASSA-PSS is different from other RSA-based signature schemes because it's probabilistic, not deterministic. It includes a randomly generated salt value. The salt boosts security by giving a "tighter" security proof than deterministic options like Full Domain Hashing (FDH). See [4] for the discussion ๐ Still, the randomness isn't critical to security. If random generation isn't possible, a fixed value or a sequence number can be used instead, and the resulting provable security is similar to FDH's [12] ๐
8.1.1 Signature generation operation
RSASSA-PSS-SIGN (K, M)
Input:
K signer's RSA private key
M message to be signed, an octet string
Output:
S signature, an octet string of length k, where k is the
length in octets of the RSA modulus n
Errors: "message too long;" "encoding error"
Steps:
- EMSA-PSS encoding: Apply the EMSA-PSS encoding operation (Section 9.1.1) to the message M to produce an encoded message EM of length \ceil ((modBits - 1)/8) octets, such that the bit length of the integer OS2IP (EM) (see Section 4.2) is at most modBits - 1. Here modBits is the length in bits of the RSA modulus n:
EM = EMSA-PSS-ENCODE (M, modBits - 1).
Note that the octet length of EM will be one less than k if modBits - 1 is divisible by 8, and equal to k otherwise. If the encoding operation outputs "message too long," output "message too long" and stop. If the encoding operation outputs "encoding error," output "encoding error" and stop. ๐
- RSA signature:
- a. Convert the encoded message EM to an integer message representative m (see Section 4.2):
m = OS2IP (EM).
- b. Apply the RSASP1 signature primitive (Section 5.2.1) to the RSA private key K and the message representative m to produce an integer signature representative s:
s = RSASP1 (K, m).
- c. Convert the signature representative s to a signature S of length k octets (see Section 4.1):
S = I2OSP (s, k).
- Output the signature S. ๐
8.1.2 Signature verification operation
RSASSA-PSS-VERIFY ((n, e), M, S)
Input:
(n, e) signer's RSA public key
M message whose signature is to be verified, an octet string
S signature to be verified, an octet string of length k, where
k is the length in octets of the RSA modulus n
Output:
"valid signature" or "invalid signature"
Steps:
- Length checking: If the length of the signature S is not k octets, output "invalid signature" and stop. ๐ โโ๏ธ
- RSA verification:
- a. Convert the signature S to an integer signature representative s (see Section 4.2):
s = OS2IP (S).
- b. Apply the RSAVP1 verification primitive (Section 5.2.2) to the RSA public key (n, e) and the signature representative s to produce an integer message representative m:
m = RSAVP1 ((n, e), s).
If RSAVP1 outputs "signature representative out of range," output "invalid signature" and stop.
- c. Convert the message representative m to an encoded message EM of length emLen = \ceil ((modBits - 1)/8) octets, where modBits is the length in bits of the RSA modulus n (see Section 4.1):
EM = I2OSP (m, emLen).
Note that emLen will be one less than k if modBits - 1 is divisible by 8, and equal to k otherwise. If I2OSP outputs "integer too large," output "invalid signature" and stop. ๐
- EMSA-PSS verification: Apply the EMSA-PSS verification operation (Section 9.1.2) to the message M and the encoded message EM to determine whether they are consistent:
Result = EMSA-PSS-VERIFY (M, EM, modBits - 1).
- If Result = "consistent," output "valid signature." Otherwise, output "invalid signature." ๐ซถ
8.2. RSASSA-PKCS1-v1_5 ๐
RSASSA-PKCS1-v1_5 is the combo where the RSASP1 and RSAVP1 primitives team up with the EMSA-PKCS1-v1_5 encoding method ๐ It's giving compatibility with the IFSSA scheme from IEEE Std 1363-2000 [26] โจ, where the signature and verification primitives are IFSP-RSA1 and IFVP-RSA1 and the message encoding method is EMSA-PKCS1-v1_5. EMSA-PKCS1-v1_5 isn't defined in IEEE Std 1363-2000, but it does show up in the IEEE P1363a draft [27] ๐
The length of messages RSASSA-PKCS1-v1_5 can operate on is either unrestricted or capped by a very large number. It depends on the hash function underneath EMSA-PKCS1-v1_5 ๐
Assuming that computing e-th roots modulo n is infeasible and the hash function in EMSA-PKCS1-v1_5 has appropriate properties, RSASSA-PKCS1-v1_5 is conjectured to provide secure signatures ๐ฅ More precisely, forging signatures without knowing the RSA private key is conjectured to be computationally infeasible ๐ Also, the EMSA-PKCS1-v1_5 encoding method embeds a hash function identifier in the encoding. So an adversary trying to find a message with the same signature as a previously signed message has to find collisions of the particular hash function being used. Attacking a different hash function than the one the signer picked is not useful to them ๐ See [34] for further discussion ๐ฆ
Note. As noted in PKCS #1 v1.5, the EMSA-PKCS1-v1_5 encoding method has the property that the encoded message, converted to an integer message representative, is guaranteed to be large and at least somewhat "random." This prevents attacks of the kind proposed by Desmedt and Odlyzko [16], where multiplicative relationships between message representatives are developed by factoring the message representatives into a set of small values (e.g., a set of small primes). Coron, Naccache, and Stern [15] showed that a stronger form of this type of attack could be quite effective against some instances of the ISO/IEC 9796-2 signature scheme. They also analyzed the complexity of this type of attack against the EMSA-PKCS1-v1_5 encoding method and concluded that an attack would be impractical, requiring more operations than a collision search on the underlying hash function (i.e., more than 2^80 operations). Coppersmith, Halevi, and Jutla [11] subsequently extended Coron et al.'s attack to break the ISO/IEC 9796-1 signature scheme with message recovery. The various attacks illustrate the importance of carefully constructing the input to the RSA signature primitive, particularly in a signature scheme with message recovery. Accordingly, the EMSA-PKCS-v1_5 encoding method explicitly includes a hash operation and is not intended for signature schemes with message recovery. Moreover, while no attack is known against the EMSA-PKCS-v1_5 encoding method, a gradual transition to EMSA-PSS is recommended as a precaution against future developments. ๐ซถ
8.2.1 Signature generation operation โจ
RSASSA-PKCS1-V1_5-SIGN (K, M)
Input:
K signer's RSA private key
M message to be signed, an octet string
Output:
S signature, an octet string of length k, where k is the
length in octets of the RSA modulus n
Errors: "message too long"; "RSA modulus too short"
Here's how the steps go ๐
- EMSA-PKCS1-v1_5 encoding: Apply the EMSA-PKCS1-v1_5 encoding operation (Section 9.2) to the message M to produce an encoded message EM of length k octets:
EM = EMSA-PKCS1-V1_5-ENCODE (M, k).
If the encoding operation outputs "message too long," output "message too long" and stop. If the encoding operation outputs "intended encoded message length too short," output "RSA modulus too short" and stop.
- RSA signature:
- a. Convert the encoded message EM to an integer message representative m (see Section 4.2):
m = OS2IP (EM).
- b. Apply the RSASP1 signature primitive (Section 5.2.1) to the RSA private key K and the message representative m to produce an integer signature representative s:
s = RSASP1 (K, m).
- c. Convert the signature representative s to a signature S of length k octets (see Section 4.1):
S = I2OSP (s, k).
- Output the signature S. ๐
8.2.2 Signature verification operation ๐
RSASSA-PKCS1-V1_5-VERIFY ((n, e), M, S)
Input:
(n, e) signer's RSA public key
M message whose signature is to be verified, an octet string
S signature to be verified, an octet string of length k, where
k is the length in octets of the RSA modulus n
Output:
"valid signature" or "invalid signature"
Errors: "message too long"; "RSA modulus too short"
Time to verify, bestie ๐ง
- Length checking: If the length of the signature S is not k octets, output "invalid signature" and stop.
- RSA verification:
- a. Convert the signature S to an integer signature representative s (see Section 4.2):
s = OS2IP (S).
- b. Apply the RSAVP1 verification primitive (Section 5.2.2) to the RSA public key (n, e) and the signature representative s to produce an integer message representative m:
m = RSAVP1 ((n, e), s).
If RSAVP1 outputs "signature representative out of range," output "invalid signature" and stop.
- c. Convert the message representative m to an encoded message EM of length k octets (see Section 4.1):
EM' = I2OSP (m, k).
If I2OSP outputs "integer too large," output "invalid signature" and stop.
- EMSA-PKCS1-v1_5 encoding: Apply the EMSA-PKCS1-v1_5 encoding operation (Section 9.2) to the message M to produce a second encoded message EM' of length k octets:
EM' = EMSA-PKCS1-V1_5-ENCODE (M, k).
If the encoding operation outputs "message too long," output "message too long" and stop. If the encoding operation outputs "intended encoded message length too short," output "RSA modulus too short" and stop.
- Compare the encoded message EM and the second encoded message EM'. If they are the same, output "valid signature"; otherwise, output "invalid signature." ๐
Note. Another way to implement the signature verification operation is to apply a "decoding" operation (not specified in this document) to the encoded message to recover the underlying hash value, and then to compare it to a newly computed hash value. This has the advantage that it requires less intermediate storage (two hash values rather than two encoded messages), but the disadvantage that it requires additional code. ๐ธ
9. Encoding methods for signatures with appendix ๐
Encoding methods are operations that map between octet string messages and octet string encoded messages. Those get converted to and from integer message representatives in the schemes, and the integer message representatives are processed via the primitives. So the encoding methods are the connection between the schemes, which process messages, and the primitives ๐ฆ
An encoding method for signatures with appendix, for the purposes of this document, consists of an encoding operation and optionally a verification operation. An encoding operation maps a message M to an encoded message EM of a specified length. A verification operation determines whether a message M and an encoded message EM are consistent, i.e., whether the encoded message EM is a valid encoding of the message M. ๐
The encoding operation may introduce some randomness, so different applications of the encoding operation to the same message will produce different encoded messages, which has benefits for provable security ๐ For such an encoding method, both an encoding and a verification operation are needed unless the verifier can reproduce the randomness (e.g., by obtaining the salt value from the signer). For a deterministic encoding method, only an encoding operation is needed. ๐
Two encoding methods for signatures with appendix are employed in the signature schemes and are specified here: EMSA-PSS and EMSA-PKCS1-v1_5. โญ
9.1 EMSA-PSS ๐
okay so this encoding method has three knobs you set up front: the hash function, the mask generation function, and the salt length. bestie, you should fix these for a given RSA key ๐, except the salt length, which is allowed to vary (check [31] if you want the drama on that). suggested hash and mask generation functions live in Appendix B ๐ธ. it's based on Bellare and Rogaway's Probabilistic Signature Scheme (PSS) [4][5], and it's randomized ๐ฒ with an encoding operation and a verification operation. it's giving clever. โจ
here's the encoding operation in one picture (Figure 2) ๐ฆ
__________________________________________________________________
+-----------+
| M |
+-----------+
|
V
Hash
|
V
+--------+----------+----------+
M' = |Padding1| mHash | salt |
+--------+----------+----------+
|
+--------+----------+ V
DB = |Padding2|maskedseed| Hash
+--------+----------+ |
| |
V | +--+
xor <--- MGF <---| |bc|
| | +--+
| | |
V V V
+-------------------+----------+--+
EM = | maskedDB |maskedseed|bc|
+-------------------+----------+--+
__________________________________________________________________
Figure 2: EMSA-PSS encoding operation. Verification operation follows reverse steps to recover salt, then forward steps to recompute and compare H. ๐
Notes. ๐
- the encoding method here is different from Bellare and Rogaway's submission to IEEE P1363a [5] in three ways, and ngl the differences are kinda iconic ๐:
- it applies a hash function rather than a mask generation function to the message. even though the mask generation function is built on a hash function, it just feels more natural to apply a hash function directly ๐ง
- the value that gets hashed together with the salt is the string
(0x)00 00 00 00 00 00 00 00 || mHash, not the message M itself. mHash is the hash of M, and the hash function is the same in both steps (see Note 3 below for more tea โ). also "salt" replaces "seed" because it matches the value's job better ๐ง - the encoded message in EMSA-PSS has nine fixed bits. the first bit is 0, and the last eight bits form a "trailer field", the octet 0xbc. in the original scheme only the first bit was fixed. the trailer field exists for compatibility with the Rabin-Williams IFSP-RW signature primitive in IEEE Std 1363-2000 [26] and the matching primitive in the draft ISO/IEC 9796-2 [29] ๐ฆ
- assuming the mask generation function is based on a hash function, it is recommended that the hash function be the same one that gets applied to the message. see Section 8.1 for more discussion ๐
- without messing up the security proof for RSASSA-PSS, you can do steps 1 and 2 of EMSA-PSS-ENCODE and EMSA-PSS-VERIFY (the hash of the message) outside the module that computes the rest of the signature operation. then mHash, not the full message M, is what goes into the module. the security proof for RSASSA-PSS still holds even if an opponent can control the value of mHash ๐. this is super handy if the module has limited I/O bandwidth, like a smart card ๐ณ. previous versions of PSS [4][5] didn't have this property. and honestly it might be desirable for other security reasons to have the module process the full message, like if it doesn't trust the component that computes the hash, then it needs to "see" what it's signing ๐
- typical salt lengths in octets are hLen (the length of the output of the hash function Hash) and 0. in both cases the security of RSASSA-PSS can be closely related to how hard it is to invert RSAVP1. Bellare and Rogaway [4] give a tight lower bound for the security of the original RSA-PSS scheme, which roughly matches the first case. Coron [12] gives a lower bound for the related Full Domain Hashing scheme, which roughly matches the second case. in [13] Coron gives a general treatment with salt lengths anywhere from 0 to hLen, so see [27] for discussion. also see [31], which adapts the security proofs in [4][13] to handle the differences between the original and the present version of RSA-PSS listed in Note 1 above ๐ง
- as noted in IEEE P1363a [27], using randomization in signature schemes (like the salt value in EMSA-PSS) may give you a "covert channel" for sending info other than the message being signed ๐ต๏ธโโ๏ธ. for more on covert channels, see [50]. no thanks to sneaky salts ๐ โโ๏ธ
9.1.1 Encoding operation ๐
Here's the encoding recipe, bestie ๐:
EMSA-PSS-ENCODE (M, emBits)
Options:
Hash hash function (hLen denotes the length in octets of the hash
function output)
MGF mask generation function
sLen intended length in octets of the salt
Input:
M message to be encoded, an octet string
emBits maximal bit length of the integer OS2IP (EM) (see Section
4.2), at least 8hLen + 8sLen + 9
Output:
EM encoded message, an octet string of length emLen = \ceil
(emBits/8)
Errors: "encoding error"; "message too long"
Steps:
1. If the length of M is greater than the input limitation for the
hash function (2^61 - 1 octets for SHA-1), output "message too
long" and stop.
2. Let mHash = Hash(M), an octet string of length hLen.
3. If emLen < hLen + sLen + 2, output "encoding error" and stop.
4. Generate a random octet string salt of length sLen; if sLen = 0,
then salt is the empty string.
5. Let
M' = (0x)00 00 00 00 00 00 00 00 || mHash || salt;
M' is an octet string of length 8 + hLen + sLen with eight
initial zero octets.
6. Let H = Hash(M'), an octet string of length hLen.
7. Generate an octet string PS consisting of emLen - sLen - hLen - 2
zero octets. The length of PS may be 0.
8. Let DB = PS || 0x01 || salt; DB is an octet string of length
emLen - hLen - 1.
9. Let dbMask = MGF(H, emLen - hLen - 1).
10. Let maskedDB = DB \xor dbMask.
11. Set the leftmost 8emLen - emBits bits of the leftmost octet in
maskedDB to zero.
12. Let EM = maskedDB || H || 0xbc.
13. Output EM.
9.1.2 Verification operation ๐
and now the checking part, where we make sure everything lines up ๐ :
EMSA-PSS-VERIFY (M, EM, emBits)
Options:
Hash hash function (hLen denotes the length in octets of the hash
function output)
MGF mask generation function
sLen intended length in octets of the salt
Input:
M message to be verified, an octet string
EM encoded message, an octet string of length emLen = \ceil
(emBits/8)
emBits maximal bit length of the integer OS2IP (EM) (see Section
4.2), at least 8hLen + 8sLen + 9
Output:
"consistent" or "inconsistent"
Steps:
1. If the length of M is greater than the input limitation for the
hash function (2^61 - 1 octets for SHA-1), output "inconsistent"
and stop.
2. Let mHash = Hash(M), an octet string of length hLen.
3. If emLen < hLen + sLen + 2, output "inconsistent" and stop.
4. If the rightmost octet of EM does not have hexadecimal value
0xbc, output "inconsistent" and stop.
5. Let maskedDB be the leftmost emLen - hLen - 1 octets of EM, and
let H be the next hLen octets.
6. If the leftmost 8emLen - emBits bits of the leftmost octet in
maskedDB are not all equal to zero, output "inconsistent" and
stop.
7. Let dbMask = MGF(H, emLen - hLen - 1).
8. Let DB = maskedDB \xor dbMask.
9. Set the leftmost 8emLen - emBits bits of the leftmost octet in DB
to zero.
10. If the emLen - hLen - sLen - 2 leftmost octets of DB are not zero
or if the octet at position emLen - hLen - sLen - 1 (the leftmost
position is "position 1") does not have hexadecimal value 0x01,
output "inconsistent" and stop.
11. Let salt be the last sLen octets of DB.
12. Let
M' = (0x)00 00 00 00 00 00 00 00 || mHash || salt ;
M' is an octet string of length 8 + hLen + sLen with eight
initial zero octets.
13. Let H' = Hash(M'), an octet string of length hLen.
14. If H = H', output "consistent." Otherwise, output "inconsistent."
that's the whole EMSA-PSS vibe, bestie, and it's literally so clean ๐โจ
9.2 EMSA-PKCS1-v1_5
Okay bestie, this encoding method is deterministic ๐ฎ and it only has an encoding operation. No decoding drama here. โจ
EMSA-PKCS1-v1_5-ENCODE (M, emLen)
Option:
Hash: hash function (hLenis the length in octets of the hash function output)
Input:
M: message to be encodedemLen: intended length in octets of the encoded message, at leasttLen + 11, wheretLenis the octet length of the DER encodingTof a certain value computed during the encoding operation
Output:
EM: encoded message, an octet string of lengthemLen
Errors:
- "message too long"; "intended encoded message length too short"
Steps:
- Hash the message
Mto get a hash valueH๐:
H = Hash(M).
If the hash function outputs "message too long," output "message too long" and stop. ๐
- Encode the algorithm ID for the hash function and the hash value into an ASN.1 value of type
DigestInfo(see Appendix A.2.4) with the Distinguished Encoding Rules (DER) ๐ . The typeDigestInfohas the syntax:
DigestInfo ::= SEQUENCE {
digestAlgorithm AlgorithmIdentifier,
digest OCTET STRING
}
The first field identifies the hash function and the second contains the hash value. Let T be the DER encoding of the DigestInfo value (see the notes below) and let tLen be the length in octets of T. ๐
- If
emLen < tLen + 11, output "intended encoded message length too short" and stop. ๐ - Generate an octet string
PSconsisting ofemLen - tLen - 3octets with hexadecimal value0xff. The length ofPSwill be at least 8 octets. ๐ธ - Concatenate
PS, the DER encodingT, and other padding to form the encoded messageEMas:
EM = 0x00 || 0x01 || PS || 0x00 || T.
- Output
EM. ๐
Notes.
- For the six hash functions mentioned in Appendix B.1, the DER encoding
Tof theDigestInfovalue is equal to the following:
MD2: (0x)30 20 30 0c 06 08 2a 86 48 86 f7 0d 02 02 05 00 04
10 || H.
MD5: (0x)30 20 30 0c 06 08 2a 86 48 86 f7 0d 02 05 05 00 04
10 || H.
SHA-1: (0x)30 21 30 09 06 05 2b 0e 03 02 1a 05 00 04 14 || H.
SHA-256: (0x)30 31 30 0d 06 09 60 86 48 01 65 03 04 02 01 05 00
04 20 || H.
SHA-384: (0x)30 41 30 0d 06 09 60 86 48 01 65 03 04 02 02 05 00
04 30 || H.
SHA-512: (0x)30 51 30 0d 06 09 60 86 48 01 65 03 04 02 03 05 00
04 40 || H.
- In version 1.5 of this document,
Twas defined as the BER encoding, rather than the DER encoding, of theDigestInfovalue. ๐ง In particular, it is possible (at least in theory) that the verification operation defined in this document (as well as in version 2.0) rejects a signature that is valid with respect to the specification given in PKCS #1 v1.5. This happens if rules other than DER are applied toDigestInfo(for example, an indefinite length encoding of the underlying SEQUENCE type). While this is unlikely to be a concern in practice, a cautious implementer MAY choose to employ a verification operation based on a BER decoding operation as specified in PKCS #1 v1.5. In this manner, compatibility with any valid implementation based on PKCS #1 v1.5 is obtained. Such a verification operation SHOULD indicate whether the underlying BER encoding is a DER encoding and hence whether the signature is valid with respect to the specification given in this document. ๐ซถ
Appendix A. ASN.1 syntax
A.1 RSA key representation
This section defines ASN.1 object identifiers for RSA public and private keys, and defines the types RSAPublicKey and RSAPrivateKey. The intended application of these definitions includes X.509 certificates, PKCS #8 [46], and PKCS #12 [47]. ๐
The object identifier rsaEncryption identifies RSA public and private keys as defined in Appendices A.1.1 and A.1.2. The parameters field associated with this OID in a value of type AlgorithmIdentifier SHALL have a value of type NULL.
rsaEncryption OBJECT IDENTIFIER ::= { pkcs-1 1 }
The definitions in this section have been extended to support multi-prime RSA, but are backward compatible with previous versions. โจ
A.1.1 RSA public key syntax
An RSA public key SHOULD be represented with the ASN.1 type RSAPublicKey:
RSAPublicKey ::= SEQUENCE {
modulus INTEGER, -- n
publicExponent INTEGER -- e
}
The fields of type RSAPublicKey have the following meanings:
modulusis the RSA modulusn.publicExponentis the RSA public exponente.
A.1.2 RSA private key syntax
An RSA private key SHOULD be represented with the ASN.1 type RSAPrivateKey:
RSAPrivateKey ::= SEQUENCE {
version Version,
modulus INTEGER, -- n
publicExponent INTEGER, -- e
privateExponent INTEGER, -- d
prime1 INTEGER, -- p
prime2 INTEGER, -- q
exponent1 INTEGER, -- d mod (p-1)
exponent2 INTEGER, -- d mod (q-1)
coefficient INTEGER, -- (inverse of q) mod p
otherPrimeInfos OtherPrimeInfos OPTIONAL
}
The fields of type RSAPrivateKey have the following meanings:
versionis the version number, for compatibility with future revisions of this document. It SHALL be 0 for this version of the document, unless multi-prime is used, in which case it SHALL be 1.
Version ::= INTEGER { two-prime(0), multi(1) }
(CONSTRAINED BY
{-- version must be multi if otherPrimeInfos present --})
modulusis the RSA modulusn.publicExponentis the RSA public exponente.privateExponentis the RSA private exponentd.prime1is the prime factorpofn.prime2is the prime factorqofn.exponent1isd mod (p - 1).exponent2isd mod (q - 1).coefficientis the CRT coefficientq^(-1) mod p.otherPrimeInfoscontains the information for the additional primesr_3, ..., r_u, in order. It SHALL be omitted ifversionis 0 and SHALL contain at least one instance ofOtherPrimeInfoifversionis 1.
OtherPrimeInfos ::= SEQUENCE SIZE(1..MAX) OF OtherPrimeInfo
OtherPrimeInfo ::= SEQUENCE {
prime INTEGER, -- ri
exponent INTEGER, -- di
coefficient INTEGER -- ti
}
The fields of type OtherPrimeInfo have the following meanings:
primeis a prime factorr_iofn, wherei >= 3.exponentisd_i = d mod (r_i - 1).coefficientis the CRT coefficientt_i = (r_1 * r_2 * ... * r_(i-1))^(-1) mod r_i.
Note. It is important to protect the RSA private key against both disclosure and modification. ๐ก๏ธ Techniques for such protection are outside the scope of this document. Methods for storing and distributing private keys and other cryptographic data are described in PKCS #12 and #15.
A.2 Scheme identification
This section defines object identifiers for the encryption and signature schemes. The schemes compatible with PKCS #1 v1.5 have the same definitions as in PKCS #1 v1.5. The intended application of these definitions includes X.509 certificates and PKCS #7. ๐
Here are type identifier definitions for the PKCS #1 OIDs:
PKCS1Algorithms ALGORITHM-IDENTIFIER ::= {
{ OID rsaEncryption PARAMETERS NULL } |
{ OID md2WithRSAEncryption PARAMETERS NULL } |
{ OID md5WithRSAEncryption PARAMETERS NULL } |
{ OID sha1WithRSAEncryption PARAMETERS NULL } |
{ OID sha256WithRSAEncryption PARAMETERS NULL } |
{ OID sha384WithRSAEncryption PARAMETERS NULL } |
{ OID sha512WithRSAEncryption PARAMETERS NULL } |
{ OID id-RSAES-OAEP PARAMETERS RSAES-OAEP-params } |
PKCS1PSourceAlgorithms |
{ OID id-RSASSA-PSS PARAMETERS RSASSA-PSS-params } ,
... -- Allows for future expansion --
}
A.2.1 RSAES-OAEP โจ
Okay bestie, the OID id-RSAES-OAEP is how we say "this is the RSAES-OAEP encryption scheme" ๐
id-RSAES-OAEP OBJECT IDENTIFIER ::= { pkcs-1 7 }
The parameters field attached to this OID in an AlgorithmIdentifier SHALL have a value of type RSAES-OAEP-params, and it looks like this ๐
RSAES-OAEP-params ::= SEQUENCE {
hashAlgorithm [0] HashAlgorithm DEFAULT sha1,
maskGenAlgorithm [1] MaskGenAlgorithm DEFAULT mgf1SHA1,
pSourceAlgorithm [2] PSourceAlgorithm DEFAULT pSpecifiedEmpty
}
So the fields of RSAES-OAEP-params mean the following ๐ฆ
hashAlgorithmnames the hash function. It SHALL be an algorithm ID with an OID in the set OAEP-PSSDigestAlgorithms. For the hash functions that are supported, check Appendix B.1 ๐ฅ
HashAlgorithm ::= AlgorithmIdentifier {
{OAEP-PSSDigestAlgorithms}
}
OAEP-PSSDigestAlgorithms ALGORITHM-IDENTIFIER ::= {
{ OID id-sha1 PARAMETERS NULL }|
{ OID id-sha256 PARAMETERS NULL }|
{ OID id-sha384 PARAMETERS NULL }|
{ OID id-sha512 PARAMETERS NULL },
... -- Allows for future expansion --
}
The default hash function is SHA-1 ๐ธ
sha1 HashAlgorithm ::= {
algorithm id-sha1,
parameters SHA1Parameters : NULL
}
SHA1Parameters ::= NULL
maskGenAlgorithmnames the mask generation function. It SHALL be an algorithm ID with an OID in the set PKCS1MGFAlgorithms, which for this version SHALL consist ofid-mgf1, the MGF1 mask generation function (see Appendix B.2.1). The parameters field associated withid-mgf1SHALL be an algorithm ID with an OID in the set OAEP-PSSDigestAlgorithms, naming the hash function that MGF1 is based on. ๐ง
MaskGenAlgorithm ::= AlgorithmIdentifier {
{PKCS1MGFAlgorithms}
}
PKCS1MGFAlgorithms ALGORITHM-IDENTIFIER ::= {
{ OID id-mgf1 PARAMETERS HashAlgorithm },
... -- Allows for future expansion --
}
The default mask generation function is MGF1 with SHA-1 โจ
mgf1SHA1 MaskGenAlgorithm ::= {
algorithm id-mgf1,
parameters HashAlgorithm : sha1
}
pSourceAlgorithmidentifies the source (and possibly the value) of the label L. It SHALL be an algorithm ID with an OID in the set PKCS1PSourceAlgorithms, which for this version SHALL consist ofid-pSpecified, meaning the label is specified explicitly. The parameters field associated withid-pSpecifiedSHALL have a value of type OCTET STRING, holding the label. Older versions of this spec said "encoding parameters" instead of "label", which is why the type below has that name ๐
PSourceAlgorithm ::= AlgorithmIdentifier {
{PKCS1PSourceAlgorithms}
}
PKCS1PSourceAlgorithms ALGORITHM-IDENTIFIER ::= {
{ OID id-pSpecified PARAMETERS EncodingParameters },
... -- Allows for future expansion --
}
id-pSpecified OBJECT IDENTIFIER ::= { pkcs-1 9 }
EncodingParameters ::= OCTET STRING(SIZE(0..MAX))
The default label is an empty string, so lHash ends up holding the hash of the empty string ๐ซถ
pSpecifiedEmpty PSourceAlgorithm ::= {
algorithm id-pSpecified,
parameters EncodingParameters : emptyString
}
emptyString EncodingParameters ::= ''H
If every field of RSAES-OAEP-params uses its default value, the algorithm identifier ends up looking like this ๐
rSAES-OAEP-Default-Identifier RSAES-AlgorithmIdentifier ::= {
algorithm id-RSAES-OAEP,
parameters RSAES-OAEP-params : {
hashAlgorithm sha1,
maskGenAlgorithm mgf1SHA1,
pSourceAlgorithm pSpecifiedEmpty
}
}
RSAES-AlgorithmIdentifier ::= AlgorithmIdentifier {
{PKCS1Algorithms}
}
A.2.2 RSAES-PKCS1-v1_5 ๐
The OID rsaEncryption (see Appendix A.1) identifies the RSAES-PKCS1-v1_5 encryption scheme. The parameters field attached to this OID in an AlgorithmIdentifier SHALL have a value of type NULL. This is the same as in PKCS #1 v1.5, so nothing new to learn here ๐ฅฐ
rsaEncryption OBJECT IDENTIFIER ::= { pkcs-1 1 }
A.2.3 RSASSA-PSS ๐
The OID id-RSASSA-PSS identifies the RSASSA-PSS encryption scheme. (That's the name the spec uses, so we're sticking with it ๐)
id-RSASSA-PSS OBJECT IDENTIFIER ::= { pkcs-1 10 }
The parameters field attached to this OID in an AlgorithmIdentifier SHALL have a value of type RSASSA-PSS-params:
RSASSA-PSS-params ::= SEQUENCE {
hashAlgorithm [0] HashAlgorithm DEFAULT sha1,
maskGenAlgorithm [1] MaskGenAlgorithm DEFAULT mgf1SHA1,
saltLength [2] INTEGER DEFAULT 20,
trailerField [3] TrailerField DEFAULT trailerFieldBC
}
The fields of RSASSA-PSS-params mean the following โจ
hashAlgorithmidentifies the hash function. It SHALL be an algorithm ID with an OID in the set OAEP-PSSDigestAlgorithms (see Appendix A.2.1). The default hash function is SHA-1.maskGenAlgorithmidentifies the mask generation function. It SHALL be an algorithm ID with an OID in the set PKCS1MGFAlgorithms (see Appendix A.2.1). The default mask generation function is MGF1 with SHA-1. For MGF1 (and more generally, for other mask generation functions based on a hash function), it is RECOMMENDED that the underlying hash function be the same as the one identified byhashAlgorithm. See Note 2 in Section 9.1 for further comments ๐ฅsaltLengthis the octet length of the salt. It SHALL be an integer. For a givenhashAlgorithm, the default value ofsaltLengthis the octet length of the hash value. Unlike the other fields of type RSASSA-PSS-params,saltLengthdoes not need to be fixed for a given RSA key pair ๐trailerFieldis the trailer field number, included for compatibility with the draft IEEE P1363a [27]. It SHALL be 1 for this version of the document, which represents the trailer field with hexadecimal value 0xbc. Other trailer fields (including the trailer field HashID || 0xcc in IEEE P1363a) are not supported in this document ๐ฆ
TrailerField ::= INTEGER { trailerFieldBC(1) }
If the default values of hashAlgorithm, maskGenAlgorithm, and trailerField are used, then the algorithm identifier ends up as ๐
rSASSA-PSS-Default-Identifier RSASSA-AlgorithmIdentifier ::= {
algorithm id-RSASSA-PSS,
parameters RSASSA-PSS-params : {
hashAlgorithm sha1,
maskGenAlgorithm mgf1SHA1,
saltLength 20,
trailerField trailerFieldBC
}
}
RSASSA-AlgorithmIdentifier ::=
AlgorithmIdentifier { {PKCS1Algorithms} }
Note. Okay, this part is lowkey a whole saga ๐ง Some applications identify the hash function separately from the rest of the signature scheme operations. For example, in PKCS #7 [45], a hash function identifier goes before the message, and a "digest encryption" algorithm identifier (covering the rest of the operations) travels with the signature. For PKCS #7 to support RSASSA-PSS, an OID would need to be defined for the operations after the hash function, the way RSAEncryption works for RSASSA-PKCS1-v1_5. S/MIME CMS [25] does it differently. A hash function identifier goes before the message, but an algorithm identifier for the full signature scheme MAY be carried with a CMS signature (this is how DSA signatures work). Following that convention, the id-RSASSA-PSS OID can be used to identify RSASSA-PSS signatures in CMS. Since CMS is seen as the successor to PKCS #7, and new work like adding RSASSA-PSS support is happening in CMS instead of PKCS #7, this version of PKCS #1 does not define an OID for the "rest of" RSASSA-PSS ๐
A.2.4 RSASSA-PKCS1-v1_5 ๐ฅ
The object identifier for RSASSA-PKCS1-v1_5 SHALL be one of the following. Which OID you pick depends on the hash algorithm: MD2, MD5, SHA-1, SHA-256, SHA-384, or SHA-512. Note that if MD2 or MD5 is used, the OID is the same as in PKCS #1 v1.5. For each OID, the parameters field attached to it in an AlgorithmIdentifier SHALL have a value of type NULL. The OID SHOULD be chosen according to this table ๐ธ
Hash algorithm OID
--------------------------------------------------------
MD2 md2WithRSAEncryption ::= {pkcs-1 2}
MD5 md5WithRSAEncryption ::= {pkcs-1 4}
SHA-1 sha1WithRSAEncryption ::= {pkcs-1 5}
SHA-256 sha256WithRSAEncryption ::= {pkcs-1 11}
SHA-384 sha384WithRSAEncryption ::= {pkcs-1 12}
SHA-512 sha512WithRSAEncryption ::= {pkcs-1 13}
The EMSA-PKCS1-v1_5 encoding method includes an ASN.1 value of type DigestInfo, and DigestInfo has this syntax ๐ง
DigestInfo ::= SEQUENCE {
digestAlgorithm DigestAlgorithm,
digest OCTET STRING
}
digestAlgorithm identifies the hash function. It SHALL be an algorithm ID with an OID in the set PKCS1-v1-5DigestAlgorithms. For the hash functions that are supported, check Appendix B.1 โจ
DigestAlgorithm ::=
AlgorithmIdentifier { {PKCS1-v1-5DigestAlgorithms} }
PKCS1-v1-5DigestAlgorithms ALGORITHM-IDENTIFIER ::= {
{ OID id-md2 PARAMETERS NULL }|
{ OID id-md5 PARAMETERS NULL }|
{ OID id-sha1 PARAMETERS NULL }|
{ OID id-sha256 PARAMETERS NULL }|
{ OID id-sha384 PARAMETERS NULL }|
{ OID id-sha512 PARAMETERS NULL }
}
Appendix B. Supporting techniques ๐ง
This appendix gives a bunch of examples of the underlying functions that support the encryption schemes in Section 7 and the encoding methods in Section 9 ๐ It offers a range of techniques so existing applications stay compatible while people migrate to newer ones. These supporting techniques are fine for applications to implement, but none of them is REQUIRED to be implemented ๐ It's expected that profiles for PKCS #1 v2.1 will be written to pin down particular supporting techniques.
This appendix also gives object identifiers for the supporting techniques ๐ฆ
B.1 Hash functions โจ
okay so hash functions are a big deal in sections 7 and 9 ๐ฅ they're deterministic, which means the output is completely locked in by the input. no surprises, no cap. they take octet strings of any length and spit out a fixed length octet string every time ๐ง
the hash functions used in sections 7 and 9 should generally be collision-resistant ๐ that means it's infeasible to find two different inputs that give the same output. a collision-resistant hash is also one-way, so given an output, it's infeasible to find an input that hashes to it. iconic behaviour ๐ญ on top of that, the hash function should yield a mask generation function (Appendix B.2) with pseudorandom output โจ
six hash functions get used as examples for the encoding methods in this document: MD2 [33], MD5 [41], SHA-1 [38], and the proposed algorithms SHA-256, SHA-384, and SHA-512 [39] ๐ธ for RSAES-OAEP and EMSA-PSS, only SHA-1 and SHA-256/384/512 are recommended. for EMSA-PKCS1-v1_5, SHA-1 or SHA-256/384/512 are recommended for new applications. MD2 and MD5 are recommended only for compatibility with existing applications that are based on PKCS #1 v1.5 ๐ซถ
the object identifiers id-md2, id-md5, id-sha1, id-sha256, id-sha384, and id-sha512 are how you identify each of these hash functions ๐ฆ
id-md2 OBJECT IDENTIFIER ::= {
iso(1) member-body(2) us(840) rsadsi(113549)
digestAlgorithm(2) 2
}
id-md5 OBJECT IDENTIFIER ::= {
iso(1) member-body(2) us(840) rsadsi(113549)
digestAlgorithm(2) 5
}
id-sha1 OBJECT IDENTIFIER ::= {
iso(1) identified-organization(3) oiw(14) secsig(3)
algorithms(2) 26
}
id-sha256 OBJECT IDENTIFIER ::= {
joint-iso-itu-t(2) country(16) us(840) organization(1)
gov(101) csor(3) nistalgorithm(4) hashalgs(2) 1
}
id-sha384 OBJECT IDENTIFIER ::= {
joint-iso-itu-t(2) country(16) us(840) organization(1)
gov(101) csor(3) nistalgorithm(4) hashalgs(2) 2
}
id-sha512 OBJECT IDENTIFIER ::= {
joint-iso-itu-t(2) country(16) us(840) organization(1)
gov(101) csor(3) nistalgorithm(4) hashalgs(2) 3
}
the parameters field linked to id-md2 and id-md5 in an AlgorithmIdentifier value shall have a value of type NULL ๐
the parameters field linked to id-sha1, id-sha256, id-sha384, and id-sha512 should be omitted, but if it's there, it shall have a value of type NULL ๐
Note. version 1.5 of PKCS #1 also let you use MD4 in signature schemes ๐ but the cryptanalysis of MD4 has moved along a lot since then. for example, Dobbertin [18] showed how to find collisions for MD4, and that the first two rounds of MD4 aren't one-way [20]. because of those results and others (e.g., [8]), MD4 is no longer recommended ๐ there have also been advances in the cryptanalysis of MD2 and MD5, but not enough to justify removing them from existing applications. Rogier and Chauvaud [43] showed how to find collisions in a modified version of MD2. nobody has shown how to find collisions for the full MD5 algorithm, though partial results have been found (e.g., [9][19]) ๐
so to deal with all this, SHA-1, SHA-256, SHA-384, or SHA-512 are recommended for new applications โจ as of today, the best known collision attacks against these hash functions are generic attacks with complexity 2^(L/2), where L is the bit length of the hash output. for the signature schemes in this document, a collision attack translates pretty easily into a signature forgery ๐ญ so the value L / 2 should be at least equal to the desired security level in bits of the signature scheme (a security level of B bits means the best attack has complexity 2^B). the same rule of thumb can be applied to RSAES-OAEP. it's recommended that the bit length of the seed (which equals the bit length of the hash output) be twice the desired security level in bits ๐
B.2 Mask generation functions ๐
a mask generation function takes an octet string of variable length and a desired output length as input, and outputs an octet string of that desired length. there may be restrictions on the lengths of the input and output octet strings, but those bounds are usually super large ๐ง mask generation functions are deterministic, so the output octet string is completely determined by the input octet string. the output should be pseudorandom: given one part of the output but not the input, it should be infeasible to predict another part of the output ๐ฆ the provable security of RSAES-OAEP and RSASSA-PSS depends on the random nature of the mask generation function's output, which in turn depends on the random nature of the underlying hash ๐ค
only one mask generation function is given here: MGF1, which is based on a hash function. MGF1 matches the mask generation functions defined in IEEE Std 1363-2000 [26] and the draft ANSI X9.44 [1] โจ future versions of this document may define other mask generation functions ๐
B.2.1 MGF1 ๐
MGF1 is a Mask Generation Function based on a hash function ๐ธ
MGF1 (mgfSeed, maskLen)
Options:
Hash hash function (hLen denotes the length in octets of the hash
function output)
Input:
mgfSeed seed from which mask is generated, an octet string
maskLen intended length in octets of the mask, at most 2^32 hLen
Output:
mask mask, an octet string of length maskLen
Error: "mask too long"
here are the steps, bestie ๐
- If
maskLen > 2^32 hLen, output"mask too long"and stop. - Let
Tbe the empty octet string. - For counter from 0 to
\ceil (maskLen / hLen) - 1, do the following:- a. Convert counter to an octet string C of length 4 octets (see Section 4.1):
C = I2OSP (counter, 4) . - b. Concatenate the hash of the seed mgfSeed and C to the octet string T:
T = T || Hash(mgfSeed || C) .
- a. Convert counter to an octet string C of length 4 octets (see Section 4.1):
- Output the leading maskLen octets of T as the octet string mask.
the object identifier id-mgf1 identifies the MGF1 mask generation function ๐ง
id-mgf1 OBJECT IDENTIFIER ::= { pkcs-1 8 }
the parameters field linked to this OID in an AlgorithmIdentifier value shall have a value of type hashAlgorithm, which identifies the hash function MGF1 is based on ๐
Appendix C. ASN.1 module ๐ฆ
PKCS-1 {
iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) pkcs-1(1)
modules(0) pkcs-1(1)
}
-- $ Revision: 2.1r1 $
-- This module has been checked for conformance with the ASN.1
-- standard by the OSS ASN.1 Tools
DEFINITIONS EXPLICIT TAGS ::=
BEGIN
-- EXPORTS ALL
-- All types and values defined in this module are exported for use
-- in other ASN.1 modules.
IMPORTS
id-sha256, id-sha384, id-sha512
FROM NIST-SHA2 {
joint-iso-itu-t(2) country(16) us(840) organization(1)
gov(101) csor(3) nistalgorithm(4) modules(0) sha2(1)
};
-- ============================
-- Basic object identifiers
-- ============================
-- The DER encoding of this in hexadecimal is:
-- (0x)06 08
-- 2A 86 48 86 F7 0D 01 01
--
pkcs-1 OBJECT IDENTIFIER ::= {
iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) 1
}
--
-- When rsaEncryption is used in an AlgorithmIdentifier the
-- parameters MUST be present and MUST be NULL.
--
rsaEncryption OBJECT IDENTIFIER ::= { pkcs-1 1 }
--
-- When id-RSAES-OAEP is used in an AlgorithmIdentifier the
-- parameters MUST be present and MUST be RSAES-OAEP-params.
--
id-RSAES-OAEP OBJECT IDENTIFIER ::= { pkcs-1 7 }
--
-- When id-pSpecified is used in an AlgorithmIdentifier the
-- parameters MUST be an OCTET STRING.
--
id-pSpecified OBJECT IDENTIFIER ::= { pkcs-1 9 }
-- When id-RSASSA-PSS is used in an AlgorithmIdentifier the
-- parameters MUST be present and MUST be RSASSA-PSS-params.
--
id-RSASSA-PSS OBJECT IDENTIFIER ::= { pkcs-1 10 }
--
-- When the following OIDs are used in an AlgorithmIdentifier the
-- parameters MUST be present and MUST be NULL.
--
md2WithRSAEncryption OBJECT IDENTIFIER ::= { pkcs-1 2 }
md5WithRSAEncryption OBJECT IDENTIFIER ::= { pkcs-1 4 }
sha1WithRSAEncryption OBJECT IDENTIFIER ::= { pkcs-1 5 }
sha256WithRSAEncryption OBJECT IDENTIFIER ::= { pkcs-1 11 }
sha384WithRSAEncryption OBJECT IDENTIFIER ::= { pkcs-1 12 }
sha512WithRSAEncryption OBJECT IDENTIFIER ::= { pkcs-1 13 }
--
-- This OID really belongs in a module with the secsig OIDs.
--
id-sha1 OBJECT IDENTIFIER ::= {
iso(1) identified-organization(3) oiw(14) secsig(3)
algorithms(2) 26
}
--
-- OIDs for MD2 and MD5, allowed only in EMSA-PKCS1-v1_5.
--
id-md2 OBJECT IDENTIFIER ::= {
iso(1) member-body(2) us(840) rsadsi(113549) digestAlgorithm(2) 2
}
id-md5 OBJECT IDENTIFIER ::= {
iso(1) member-body(2) us(840) rsadsi(113549) digestAlgorithm(2) 5
}
--
-- When id-mgf1 is used in an AlgorithmIdentifier the parameters MUST
-- be present and MUST be a HashAlgorithm, for example sha1.
--
id-mgf1 OBJECT IDENTIFIER ::= { pkcs-1 8 }
-- ================
-- Useful types
-- ================
ALGORITHM-IDENTIFIER ::= CLASS {
&id OBJECT IDENTIFIER UNIQUE,
&Type OPTIONAL
}
WITH SYNTAX { OID &id [PARAMETERS &Type] }
--
-- Note: the parameter InfoObjectSet in the following definitions
-- allows a distinct information object set to be specified for sets
-- of algorithms such as:
-- DigestAlgorithms ALGORITHM-IDENTIFIER ::= {
-- { OID id-md2 PARAMETERS NULL }|
-- { OID id-md5 PARAMETERS NULL }|
-- { OID id-sha1 PARAMETERS NULL }
-- }
--
AlgorithmIdentifier { ALGORITHM-IDENTIFIER:InfoObjectSet } ::=
SEQUENCE {
algorithm ALGORITHM-IDENTIFIER.&id({InfoObjectSet}),
parameters
ALGORITHM-IDENTIFIER.&Type({InfoObjectSet}{@.algorithm})
OPTIONAL
}
-- ==============
-- Algorithms
-- ==============
--
-- Allowed EME-OAEP and EMSA-PSS digest algorithms.
--
OAEP-PSSDigestAlgorithms ALGORITHM-IDENTIFIER ::= {
{ OID id-sha1 PARAMETERS NULL }|
{ OID id-sha256 PARAMETERS NULL }|
{ OID id-sha384 PARAMETERS NULL }|
{ OID id-sha512 PARAMETERS NULL },
... -- Allows for future expansion --
}
--
-- Allowed EMSA-PKCS1-v1_5 digest algorithms.
--
PKCS1-v1-5DigestAlgorithms ALGORITHM-IDENTIFIER ::= {
{ OID id-md2 PARAMETERS NULL }|
{ OID id-md5 PARAMETERS NULL }|
{ OID id-sha1 PARAMETERS NULL }|
{ OID id-sha256 PARAMETERS NULL }|
{ OID id-sha384 PARAMETERS NULL }|
{ OID id-sha512 PARAMETERS NULL }
}
-- When id-md2 and id-md5 are used in an AlgorithmIdentifier the
-- parameters MUST be present and MUST be NULL.
-- When id-sha1, id-sha256, id-sha384 and id-sha512 are used in an
-- AlgorithmIdentifier the parameters (which are optional) SHOULD
-- be omitted. However, an implementation MUST also accept
-- AlgorithmIdentifier values where the parameters are NULL.
sha1 HashAlgorithm ::= {
algorithm id-sha1,
parameters SHA1Parameters : NULL -- included for compatibility
-- with existing implementations
}
HashAlgorithm ::= AlgorithmIdentifier { {OAEP-PSSDigestAlgorithms} }
SHA1Parameters ::= NULL
--
-- Allowed mask generation function algorithms.
-- If the identifier is id-mgf1, the parameters are a HashAlgorithm.
--
PKCS1MGFAlgorithms ALGORITHM-IDENTIFIER ::= {
{ OID id-mgf1 PARAMETERS HashAlgorithm },
... -- Allows for future expansion --
}
--
-- Default AlgorithmIdentifier for id-RSAES-OAEP.maskGenAlgorithm and
-- id-RSASSA-PSS.maskGenAlgorithm.
--
mgf1SHA1 MaskGenAlgorithm ::= {
algorithm id-mgf1,
parameters HashAlgorithm : sha1
}
MaskGenAlgorithm ::= AlgorithmIdentifier { {PKCS1MGFAlgorithms} }
--
-- Allowed algorithms for pSourceAlgorithm.
--
PKCS1PSourceAlgorithms ALGORITHM-IDENTIFIER ::= {
{ OID id-pSpecified PARAMETERS EncodingParameters },
... -- Allows for future expansion --
}
EncodingParameters ::= OCTET STRING(SIZE(0..MAX))
--
-- This identifier means that the label L is an empty string, so the
-- digest of the empty string appears in the RSA block before
-- masking.
--
pSpecifiedEmpty PSourceAlgorithm ::= {
algorithm id-pSpecified,
parameters EncodingParameters : emptyString
}
PSourceAlgorithm ::= AlgorithmIdentifier { {PKCS1PSourceAlgorithms} }
emptyString EncodingParameters ::= ''H
--
-- Type identifier definitions for the PKCS #1 OIDs.
--
PKCS1Algorithms ALGORITHM-IDENTIFIER ::= {
{ OID rsaEncryption PARAMETERS NULL } |
{ OID md2WithRSAEncryption PARAMETERS NULL } |
{ OID md5WithRSAEncryption PARAMETERS NULL } |
{ OID sha1WithRSAEncryption PARAMETERS NULL } |
{ OID sha256WithRSAEncryption PARAMETERS NULL } |
{ OID sha384WithRSAEncryption PARAMETERS NULL } |
{ OID sha512WithRSAEncryption PARAMETERS NULL } |
{ OID id-RSAES-OAEP PARAMETERS RSAES-OAEP-params } |
PKCS1PSourceAlgorithms |
{ OID id-RSASSA-PSS PARAMETERS RSASSA-PSS-params } ,
... -- Allows for future expansion --
}
-- ===================
-- Main structures
-- ===================
RSAPublicKey ::= SEQUENCE {
modulus INTEGER, -- n
publicExponent INTEGER -- e
}
--
-- Representation of RSA private key with information for the CRT
-- algorithm.
--
RSAPrivateKey ::= SEQUENCE {
version Version,
modulus INTEGER, -- n
publicExponent INTEGER, -- e
privateExponent INTEGER, -- d
prime1 INTEGER, -- p
prime2 INTEGER, -- q
exponent1 INTEGER, -- d mod (p-1)
exponent2 INTEGER, -- d mod (q-1)
coefficient INTEGER, -- (inverse of q) mod p
otherPrimeInfos OtherPrimeInfos OPTIONAL
}
Version ::= INTEGER { two-prime(0), multi(1) }
(CONSTRAINED BY {
-- version must be multi if otherPrimeInfos present --
})
OtherPrimeInfos ::= SEQUENCE SIZE(1..MAX) OF OtherPrimeInfo
OtherPrimeInfo ::= SEQUENCE {
prime INTEGER, -- ri
exponent INTEGER, -- di
coefficient INTEGER -- ti
}
--
-- AlgorithmIdentifier.parameters for id-RSAES-OAEP.
-- Note that the tags in this Sequence are explicit.
--
RSAES-OAEP-params ::= SEQUENCE {
hashAlgorithm [0] HashAlgorithm DEFAULT sha1,
maskGenAlgorithm [1] MaskGenAlgorithm DEFAULT mgf1SHA1,
pSourceAlgorithm [2] PSourceAlgorithm DEFAULT pSpecifiedEmpty
}
--
-- Identifier for default RSAES-OAEP algorithm identifier.
-- The DER Encoding of this is in hexadecimal:
-- (0x)30 0D
-- 06 09
-- 2A 86 48 86 F7 0D 01 01 07
-- 30 00
-- Notice that the DER encoding of default values is "empty".
--
rSAES-OAEP-Default-Identifier RSAES-AlgorithmIdentifier ::= {
algorithm id-RSAES-OAEP,
parameters RSAES-OAEP-params : {
hashAlgorithm sha1,
maskGenAlgorithm mgf1SHA1,
pSourceAlgorithm pSpecifiedEmpty
}
}
RSAES-AlgorithmIdentifier ::=
AlgorithmIdentifier { {PKCS1Algorithms} }
--
-- AlgorithmIdentifier.parameters for id-RSASSA-PSS.
-- Note that the tags in this Sequence are explicit.
--
RSASSA-PSS-params ::= SEQUENCE {
hashAlgorithm [0] HashAlgorithm DEFAULT sha1,
maskGenAlgorithm [1] MaskGenAlgorithm DEFAULT mgf1SHA1,
saltLength [2] INTEGER DEFAULT 20,
trailerField [3] TrailerField DEFAULT trailerFieldBC
}
TrailerField ::= INTEGER { trailerFieldBC(1) }
--
-- Identifier for default RSASSA-PSS algorithm identifier
-- The DER Encoding of this is in hexadecimal:
-- (0x)30 0D
-- 06 09
-- 2A 86 48 86 F7 0D 01 01 0A
-- 30 00
-- Notice that the DER encoding of default values is "empty".
--
rSASSA-PSS-Default-Identifier RSASSA-AlgorithmIdentifier ::= {
algorithm id-RSASSA-PSS,
parameters RSASSA-PSS-params : {
hashAlgorithm sha1,
maskGenAlgorithm mgf1SHA1,
saltLength 20,
trailerField trailerFieldBC
}
}
RSASSA-AlgorithmIdentifier ::=
AlgorithmIdentifier { {PKCS1Algorithms} }
--
-- Syntax for the EMSA-PKCS1-v1_5 hash identifier.
--
DigestInfo ::= SEQUENCE {
digestAlgorithm DigestAlgorithm,
digest OCTET STRING
}
DigestAlgorithm ::=
AlgorithmIdentifier { {PKCS1-v1-5DigestAlgorithms} }
END -- PKCS1Definitions
Appendix D. Intellectual Property Considerations โจ
okay the patent stuff is kinda a whole saga, so let's go through it ๐
The RSA public-key cryptosystem is described in U.S. Patent 4,405,829, and that one expired on September 20, 2000. ๐ฆ RSA Security Inc. says it makes no other patent claims on the constructions in this document, although specific underlying techniques may still be covered, so keep that in mind ๐
Multi-prime RSA is described in U.S. Patent 5,848,159. ๐ธ
The University of California has a patent pending on the PSS signature scheme [5]. It also sent a letter to the IEEE P1363 working group saying that if PSS ends up in an IEEE standard, "the University of California will, when that standard is adopted, FREELY license any conforming implementation of PSS as a technique for achieving a digital signature with appendix" [23]. That's giving generous energy ๐ซถ The PSS signature scheme is specified in the IEEE P1363a draft [27], which was still in ballot resolution when this document was published ๐
Copying this document is allowed, as long as it's identified as "RSA Security Inc. Public-Key Cryptography Standards (PKCS)" in all material that mentions or references it ๐
RSA Security Inc. makes no other representations about intellectual property claims by other parties. Figuring out whether those claims apply is the responsibility of the user, so do your homework bestie ๐
Appendix E. Revision history ๐ง
Versions 1.0 - 1.3
Versions 1.0 - 1.3 went out to participants in RSA Data Security, Inc.'s Public-Key Cryptography Standards meetings in February and March 1991 ๐
Version 1.4
Version 1.4 was part of the June 3, 1991 initial public release of PKCS ๐ It got published as NIST/OSI Implementors' Workshop document SEC-SIG-91-18.
Version 1.5
Version 1.5 had a bunch of editorial changes, including updated references and a brand new revision history section. The substantive changes were:
- Section 10: "MD4 with RSA" signature and verification processes were added. ๐ฅ
- Section 11: the
md4WithRSAEncryptionobject identifier was added. ๐
Version 1.5 was republished as IETF RFC 2313 โจ
Version 2.0
Version 2.0 was a major editorial glow-up in terms of document structure, and it introduced the RSAES-OAEP encryption scheme ๐ It kept supporting the encryption and signature processes from version 1.5, with one big change: MD4 was no longer allowed, because cryptanalytic advances in the years since made it unsafe to keep around ๐ Version 2.0 was republished as IETF RFC 2437 [35].
Version 2.1
Version 2.1 brings in multi-prime RSA and the RSASSA-PSS signature scheme with appendix, plus several editorial improvements ๐ธ It keeps supporting the schemes from version 2.0, so nothing got left behind ๐ซถ
Appendix F: References โจ
okay bestie, this is the reading list ๐๐ fifty sources, and honestly the security papers in here are where the drama lives ๐ every citation is kept exactly as written so you can go find the originals ๐ซถ
- [1] ANSI X9F1 Working Group. ANSI X9.44 Draft D2: Key Establishment Using Integer Factorization Cryptography. Working Draft, March 2002.
- [2] M. Bellare, A. Desai, D. Pointcheval and P. Rogaway. Relations Among Notions of Security for Public-Key Encryption Schemes. In H. Krawczyk, editor, Advances in Cryptology - Crypto '98, volume 1462 of Lecture Notes in Computer Science, pp. 26 - 45. Springer Verlag, 1998.
- [3] M. Bellare and P. Rogaway. Optimal Asymmetric Encryption - How to Encrypt with RSA. In A. De Santis, editor, Advances in Cryptology - Eurocrypt '94, volume 950 of Lecture Notes in Computer Science, pp. 92 - 111. Springer Verlag, 1995.
- [4] M. Bellare and P. Rogaway. The Exact Security of Digital Signatures - How to Sign with RSA and Rabin. In U. Maurer, editor, Advances in Cryptology - Eurocrypt '96, volume 1070 of Lecture Notes in Computer Science, pp. 399 - 416. Springer Verlag, 1996.
- [5] M. Bellare and P. Rogaway. PSS: Provably Secure Encoding Method for Digital Signatures. Submission to IEEE P1363 working group, August 1998. Available from
http://grouper.ieee.org/groups/1363/. - [6] D. Bleichenbacher. Chosen Ciphertext Attacks Against Protocols Based on the RSA Encryption Standard PKCS #1. In H. Krawczyk, editor, Advances in Cryptology - Crypto '98, volume 1462 of Lecture Notes in Computer Science, pp. 1 - 12. Springer Verlag, 1998.
- [7] D. Bleichenbacher, B. Kaliski and J. Staddon. Recent Results on PKCS #1: RSA Encryption Standard. RSA Laboratories' Bulletin No. 7, June 1998.
- [8] B. den Boer and A. Bosselaers. An Attack on the Last Two Rounds of MD4. In J. Feigenbaum, editor, Advances in Cryptology - Crypto '91, volume 576 of Lecture Notes in Computer Science, pp. 194 - 203. Springer Verlag, 1992.
- [9] B. den Boer and A. Bosselaers. Collisions for the Compression Function of MD5. In T. Helleseth, editor, Advances in Cryptology - Eurocrypt '93, volume 765 of Lecture Notes in Computer Science, pp. 293 - 304. Springer Verlag, 1994.
- [10] D. Coppersmith, M. Franklin, J. Patarin and M. Reiter. Low-Exponent RSA with Related Messages. In U. Maurer, editor, Advances in Cryptology - Eurocrypt '96, volume 1070 of Lecture Notes in Computer Science, pp. 1 - 9. Springer Verlag, 1996.
- [11] D. Coppersmith, S. Halevi and C. Jutla. ISO 9796-1 and the New Forgery Strategy. Presented at the rump session of Crypto '99, August 1999.
- [12] J.-S. Coron. On the Exact Security of Full Domain Hashing. In M. Bellare, editor, Advances in Cryptology - Crypto 2000, volume 1880 of Lecture Notes in Computer Science, pp. 229 - 235. Springer Verlag, 2000.
- [13] J.-S. Coron. Optimal Security Proofs for PSS and Other Signature Schemes. In L. Knudsen, editor, Advances in Cryptology - Eurocrypt 2002, volume 2332 of Lecture Notes in Computer Science, pp. 272 - 287. Springer Verlag, 2002.
- [14] J.-S. Coron, M. Joye, D. Naccache and P. Paillier. New Attacks on PKCS #1 v1.5 Encryption. In B. Preneel, editor, Advances in Cryptology - Eurocrypt 2000, volume 1807 of Lecture Notes in Computer Science, pp. 369 - 379. Springer Verlag, 2000.
- [15] J.-S. Coron, D. Naccache and J. P. Stern. On the Security of RSA Padding. In M. Wiener, editor, Advances in Cryptology - Crypto '99, volume 1666 of Lecture Notes in Computer Science, pp. 1 - 18. Springer Verlag, 1999.
- [16] Y. Desmedt and A.M. Odlyzko. A Chosen Text Attack on the RSA Cryptosystem and Some Discrete Logarithm Schemes. In H.C. Williams, editor, Advances in Cryptology - Crypto '85, volume 218 of Lecture Notes in Computer Science, pp. 516 - 522. Springer Verlag, 1986.
- [17] Dierks, T. and C. Allen, "The TLS Protocol, Version 1.0", RFC 2246, January 1999.
- [18] H. Dobbertin. Cryptanalysis of MD4. In D. Gollmann, editor, Fast Software Encryption '96, volume 1039 of Lecture Notes in Computer Science, pp. 55 - 72. Springer Verlag, 1996.
- [19] H. Dobbertin. Cryptanalysis of MD5 Compress. Presented at the rump session of Eurocrypt '96, May 1996.
- [20] H. Dobbertin. The First Two Rounds of MD4 are Not One-Way. In S. Vaudenay, editor, Fast Software Encryption '98, volume 1372 in Lecture Notes in Computer Science, pp. 284 - 292. Springer Verlag, 1998.
- [21] E. Fujisaki, T. Okamoto, D. Pointcheval and J. Stern. RSA-OAEP is Secure under the RSA Assumption. In J. Kilian, editor, Advances in Cryptology - Crypto 2001, volume 2139 of Lecture Notes in Computer Science, pp. 260 - 274. Springer Verlag, 2001.
- [22] H. Garner. The Residue Number System. IRE Transactions on Electronic Computers, EC-8 (6), pp. 140 - 147, June 1959.
- [23] M.L. Grell. Re: Encoding Methods PSS/PSS-R. Letter to IEEE P1363 working group, University of California, June 15, 1999. Available from
http://grouper.ieee.org/groups/1363/P1363/patents.html. - [24] J. Haastad. Solving Simultaneous Modular Equations of Low Degree. SIAM Journal of Computing, volume 17, pp. 336 - 341, 1988.
- [25] Housley, R., "Cryptographic Message Syntax (CMS)", RFC 3369, August 2002. Housley, R., "Cryptographic Message Syntax (CMS) Algorithms", RFC 3370, August 2002.
- [26] IEEE Std 1363-2000: Standard Specifications for Public Key Cryptography. IEEE, August 2000.
- [27] IEEE P1363 working group. IEEE P1363a D11: Draft Standard Specifications for Public Key Cryptography -- Amendment 1: Additional Techniques. December 16, 2002. Available from
http://grouper.ieee.org/groups/1363/. - [28] ISO/IEC 9594-8:1997: Information technology - Open Systems Interconnection - The Directory: Authentication Framework. 1997.
- [29] ISO/IEC FDIS 9796-2: Information Technology - Security Techniques - Digital Signature Schemes Giving Message Recovery - Part 2: Integer Factorization Based Mechanisms. Final Draft International Standard, December 2001.
- [30] ISO/IEC 18033-2: Information Technology - Security Techniques - Encryption Algorithms - Part 2: Asymmetric Ciphers. V. Shoup, editor, Text for 2nd Working Draft, January 2002.
- [31] J. Jonsson. Security Proof for the RSA-PSS Signature Scheme (extended abstract). Second Open NESSIE Workshop. September 2001. Full version available from
http://eprint.iacr.org/2001/053/. - [32] J. Jonsson and B. Kaliski. On the Security of RSA Encryption in TLS. In M. Yung, editor, Advances in Cryptology - CRYPTO 2002, vol. 2442 of Lecture Notes in Computer Science, pp. 127 - 142. Springer Verlag, 2002.
- [33] Kaliski, B., "The MD2 Message-Digest Algorithm", RFC 1319, April 1992.
- [34] B. Kaliski. On Hash Function Identification in Signature Schemes. In B. Preneel, editor, RSA Conference 2002, Cryptographers' Track, volume 2271 of Lecture Notes in Computer Science, pp. 1 - 16. Springer Verlag, 2002.
- [35] Kaliski, B. and J. Staddon, "PKCS #1: RSA Cryptography Specifications Version 2.0", RFC 2437, October 1998.
- [36] J. Manger. A Chosen Ciphertext Attack on RSA Optimal Asymmetric Encryption Padding (OAEP) as Standardized in PKCS #1 v2.0. In J. Kilian, editor, Advances in Cryptology - Crypto 2001, volume 2139 of Lecture Notes in Computer Science, pp. 260 - 274. Springer Verlag, 2001.
- [37] A. Menezes, P. van Oorschot and S. Vanstone. Handbook of Applied Cryptography. CRC Press, 1996.
- [38] National Institute of Standards and Technology (NIST). FIPS Publication 180-1: Secure Hash Standard. April 1994.
- [39] National Institute of Standards and Technology (NIST). Draft FIPS 180-2: Secure Hash Standard. Draft, May 2001. Available from
http://www.nist.gov/sha/. - [40] J.-J. Quisquater and C. Couvreur. Fast Decipherment Algorithm for RSA Public-Key Cryptosystem. Electronics Letters, 18 (21), pp. 905 - 907, October 1982.
- [41] Rivest, R., "The MD5 Message-Digest Algorithm", RFC 1321, April 1992.
- [42] R. Rivest, A. Shamir and L. Adleman. A Method for Obtaining Digital Signatures and Public-Key Cryptosystems. Communications of the ACM, 21 (2), pp. 120-126, February 1978.
- [43] N. Rogier and P. Chauvaud. The Compression Function of MD2 is not Collision Free. Presented at Selected Areas of Cryptography '95. Carleton University, Ottawa, Canada. May 1995.
- [44] RSA Laboratories. PKCS #1 v2.0: RSA Encryption Standard. October 1998.
- [45] RSA Laboratories. PKCS #7 v1.5: Cryptographic Message Syntax Standard. November 1993. (Republished as IETF RFC 2315.)
- [46] RSA Laboratories. PKCS #8 v1.2: Private-Key Information Syntax Standard. November 1993.
- [47] RSA Laboratories. PKCS #12 v1.0: Personal Information Exchange Syntax Standard. June 1999.
- [48] V. Shoup. OAEP Reconsidered. In J. Kilian, editor, Advances in Cryptology - Crypto 2001, volume 2139 of Lecture Notes in Computer Science, pp. 239 - 259. Springer Verlag, 2001.
- [49] R. D. Silverman. A Cost-Based Security Analysis of Symmetric and Asymmetric Key Lengths. RSA Laboratories Bulletin No. 13, April 2000. Available from
http://www.rsasecurity.com.rsalabs/bulletins/. - [50] G. J. Simmons. Subliminal communication is easy using the DSA. In T. Helleseth, editor, Advances in Cryptology - Eurocrypt '93, volume 765 of Lecture Notes in Computer Science, pp. 218- 232. Springer-Verlag, 1993.
Appendix G: About PKCS ๐
so, the Public-Key Cryptography Standards are specs made by RSA Laboratories together with secure systems developers all over the world ๐ the goal was to speed up how fast public-key crypto gets deployed, and it's giving main character energy ๐ they first came out in 1991 after meetings with a small crew of early adopters, and now the PKCS docs are everywhere โจ
a bunch of their stuff ended up inside many formal and de facto standards, like ANSI X9 and IEEE P1363 documents, PKIX, SET, S/MIME, SSL/TLS, and WAP/WTLS. iconic ๐ฅ
further development happens through mailing list discussions and the occasional workshop, and suggestions for improvement are welcome ๐ซถ if you want to reach out, here's the contact info:
PKCS Editor
RSA Laboratories
174 Middlesex Turnpike
Bedford, MA 01730 USA
pkcs-editor@rsasecurity.com
http://www.rsasecurity.com/rsalabs/pkcs
Appendix H: Corrections Made During RFC Publication Process โจ
okay so bestie, these are the fixes that got made when the PKCS #1 v2.1 doc was turned into this RFC ๐
- The requirement that the parameters in an
AlgorithmIdentifiervalue forid-sha1,id-sha256,id-sha384, andid-sha512beNULLgot switched to a recommendation that the parameters be omitted (while still allowing the parameters to beNULL). This lines up with the definitions NIST originally put out ๐ Implementations MUST acceptAlgorithmIdentifiervalues both without parameters and withNULLparameters. ๐ซถ - The notes after RSADP and RSASP1 (Secs. 5.1.2 and 5.2.1) now point to step 2.b instead of 2.a ๐
- References [25], [27] and [32] got updated with new publication data ๐
These corrections will be reflected in future editions of PKCS #1 v2.1 ๐ธ
Security Considerations ๐
Security is the whole vibe here, bestie ๐ญ Security issues are discussed throughout this memo, so don't skip anything ๐
Acknowledgements ๐
This document is based on a contribution of RSA Laboratories, the research center of RSA Security Inc. ๐ Any substantial use of the text from this document must acknowledge RSA Security Inc. RSA Security Inc. requests that all material mentioning or referencing this document identify this as "RSA Security Inc. PKCS #1 v2.1" ๐ซถ
Authors' Addresses ๐ฆ
Here are the people who made this happen, with their contact info โจ
Jakob Jonsson
Philipps-Universitaet Marburg
Fachbereich Mathematik und Informatik
Hans Meerwein Strasse, Lahnberge
DE-35032 Marburg
Germany
Phone: +49 6421 28 25672
EMail: jonsson@mathematik.uni-marburg.de
Burt Kaliski
RSA Laboratories
174 Middlesex Turnpike
Bedford, MA 01730 USA
Phone: +1 781 515 7073
EMail: bkaliski@rsasecurity.com
Full Copyright Statement ๐
Legal stuff, but it matters, so read it ๐ซถ
Copyright (C) The Internet Society 2003. All Rights Reserved.
This document and translations of it may be copied and furnished to others provided that the above copyright notice and this paragraph are included on all such copies. However, this document itself may not be modified in any way, such as by removing the copyright notice or references to the Internet Society or other Internet organizations, except as required to translate it into languages other than English.
The limited permissions granted above are perpetual and will not be revoked by the Internet Society or its successors or assigns.
This document and the information contained herein is provided on an "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
Acknowledgement ๐
Funding for the RFC Editor function is currently provided by the Internet Society ๐
๐ฆ where this page comes from
- ietf: rfc3447 2003-02
- ๐ girlified by claude-haiku-5-5 on : a language model's rewrite of the original, under its terms