RFC 8017 - PKCS #1: RSA 密码学规范版本 2.2
- 状态: Informational
- 发布日期: 2016 年 11 月
- Stream: IETF
- 废弃了: RFC3447
- 勘误: 无勘误
摘要 (Abstract)
本文档提供基于 RSA 算法实现公钥密码学的建议, 涵盖密码学原语, 加密方案, 带附录的签名方案, 以及用于表示密钥和标识方案的 ASN.1 语法.
本文档是 RSA Laboratories 的 Public-Key Cryptography Standards (PKCS) 系列中 PKCS #1 v2.2 的重新发布版本. 通过发布此 RFC, 变更控制权转移给 IETF.
本文档也废弃 RFC 3447.
本备忘录状态 (Status of This Memo)
本文档不是 Internet 标准路线规范. 它作为信息性文档发布.
本文档是 Internet Engineering Task Force (IETF) 的产物. 它代表 IETF 社区的共识. 它已经接受公开审查, 并获 Internet Engineering Steering Group (IESG) 批准发布. 并非所有经 IESG 批准的文档都是某一级别 Internet Standard 的候选文档. 见 RFC 7841 第 2 节.
关于本文档当前状态, 任何勘误以及如何提供反馈的信息, 可从 ````http://www.rfc-editor.org/info/rfc8017\```` 获取.
目录 (Table of Contents)
- 1. 引言 (Introduction)
- 1.1 要求语言 (Requirements Language)
- 2. 记法 (Notation)
- 3. 密钥类型 (Key Types)
- 3.1 RSA 公钥 (RSA Public Key)
- 3.2 RSA 私钥 (RSA Private Key)
- 4. 数据转换原语 (Data Conversion Primitives)
- 4.1 I2OSP
- 4.2 OS2IP
- 5. 密码学原语 (Cryptographic Primitives)
- 5.1 加密和解密原语 (Encryption and Decryption Primitives)
- 5.2 签名和验证原语 (Signature and Verification Primitives)
- 6. 方案概述 (Overview of Schemes)
- 7. 加密方案 (Encryption Schemes)
- 7.1 RSAES-OAEP
- 7.2 RSAES-PKCS1-v1_5
- 8. 带附录的签名方案 (Signature Scheme with Appendix)
- 8.1 RSASSA-PSS
- 8.2 RSASSA-PKCS1-v1_5
- 9. 带附录签名的编码方法 (Encoding Methods for Signatures with Appendix)
- 9.1 EMSA-PSS
- 9.2 EMSA-PKCS1-v1_5
- 10. 安全考虑事项 (Security Considerations)
- 11. 参考文献 (References)
- 11.1 规范性参考文献 (Normative References)
- 11.2 信息性参考文献 (Informative References)
附录 (Appendices)
- Appendix A. ASN.1 语法 (ASN.1 Syntax)
- A.1 RSA 密钥表示 (RSA Key Representation)
- A.2 方案标识 (Scheme Identification)
- Appendix B. 支持技术 (Supporting Techniques)
- B.1 哈希函数 (Hash Functions)
- B.2 掩码生成函数 (Mask Generation Functions)
- Appendix C. ASN.1 模块 (ASN.1 Module)
- Appendix D. PKCS #1 修订历史 (Revision History of PKCS #1)
- Appendix E. 关于 PKCS (About PKCS)
相关资源 (Related Resources)
- Official Text: RFC 8017
- Official Page: RFC 8017 DataTracker
- Errata: RFC Editor Errata
- Obsoleted Document: RFC 3447 (PKCS #1 v2.1)
1. Introduction (简介)
本文档为基于RSA算法 [RSA] 的公钥密码学实现提供建议,涵盖以下方面:
- 密码学原语 (Cryptographic primitives)
- 加密方案 (Encryption schemes)
- 带附录的签名方案 (Signature schemes with appendix)
- 用于表示密钥和标识方案的ASN.1语法
这些建议旨在在计算机和通信系统中通用应用,因此包含相当大的灵活性. 基于这些规范的应用标准可能会包含额外的约束. 这些建议旨在与IEEE 1363 [IEEE1363]、IEEE 1363a [IEEE1363A]和ANSI X9.44 [ANSIX944]标准兼容.
本文档取代PKCS #1版本2.1 [RFC3447],但包含兼容的技术.
本文档的组织结构如下:
-
第1节是简介.
-
第2节定义本文档中使用的一些符号约定.
-
第3节定义RSA公钥和私钥类型.
-
第4节和第5节定义几个原语 (Primitives),或基本数学运算. 数据转换原语在第4节,密码学原语 (加密-解密和签名-验证) 在第5节.
-
第6、7和8节涉及本文档中的加密和签名方案. 第6节给出概述. 除了PKCS #1 v1.5中的方法外,第7节定义基于最优非对称加密填充 (Optimal Asymmetric Encryption Padding, OAEP) [OAEP]的加密方案,第8节定义基于概率签名方案 (Probabilistic Signature Scheme, PSS) [RSARABIN] [PSS]的带附录签名方案.
-
第9节定义第8节中签名方案的编码方法.
-
附录A定义第3节中定义的密钥以及第7节和第8节中方案的ASN.1语法.
-
附录B定义本文档中使用的哈希函数 (Hash Functions) 和掩码生成函数 (Mask Generation Function, MGF),包括这些技术的ASN.1语法.
-
附录C给出ASN.1模块.
-
附录D和E概述PKCS #1的修订历史,并提供关于公钥密码学标准 (Public-Key Cryptography Standards) 的一般信息.
本文档代表RSA实验室公钥密码学标准 (PKCS) 系列中PKCS #1 v2.2 [PKCS1_22]的重新发布.
1.1. Requirements Language (要求语言)
本文档中的关键词 "MUST" (必须)、"MUST NOT" (禁止)、"REQUIRED" (必需)、"SHALL" (应)、"SHALL NOT" (不应)、"SHOULD" (应该)、"SHOULD NOT" (不应该)、"RECOMMENDED" (推荐)、"MAY" (可以) 和 "OPTIONAL" (可选) 应按照 [RFC2119] 中的描述进行解释.
2. Notation (符号约定)
本文档中的符号约定包括:
| 符号 | 含义 |
|---|---|
| c | 密文代表值 (Ciphertext Representative),一个介于0和n-1之间的整数 |
| C | 密文 (Ciphertext),一个八位字节串 (Octet String) |
| d | RSA私钥指数 (RSA Private Exponent) |
| d_i | 额外因子r_i的CRT指数 (Additional Factor r_i's CRT Exponent),一个正整数,满足: e * d_i == 1 (mod (r_i-1)), i = 3, ..., u |
| dP | p的CRT指数,一个正整数,满足: e * dP == 1 (mod (p-1)) |
| dQ | q的CRT指数,一个正整数,满足: e * dQ == 1 (mod (q-1)) |
| e | RSA公钥指数 (RSA Public Exponent) |
| EM | 编码消息 (Encoded Message),一个八位字节串 |
| emBits | 编码消息EM的(预期)比特长度 |
| emLen | 编码消息EM的(预期)八位字节长度 |
| GCD(. , .) | 两个非负整数的最大公约数 (Greatest Common Divisor) |
| Hash | 哈希函数 (Hash Function) |
| hLen | 哈希函数Hash的输出长度(以八位字节为单位) |
| k | RSA模数n的长度(以八位字节为单位) |
| K | RSA私钥 (RSA Private Key) |
| L | 可选的RSAES-OAEP标签 (Label),一个八位字节串 |
| LCM(., ..., .) | 非负整数列表的最小公倍数 (Least Common Multiple) |
| m | 消息代表值 (Message Representative),一个介于0和n-1之间的整数 |
| M | 消息 (Message),一个八位字节串 |
| mask | MGF输出,一个八位字节串 |
| maskLen | 八位字节串mask的(预期)长度 |
| MGF | 掩码生成函数 (Mask Generation Function) |
| mgfSeed | 生成掩码的种子 (Seed),一个八位字节串 |
| mLen | 消息M的长度(以八位字节为单位) |
| n | RSA模数 (RSA Modulus), n = r_1 * r_2 * ... * r_u, u >= 2 |
| (n, e) | RSA公钥 (RSA Public Key) |
| p, q | RSA模数n的前两个素因子 (Prime Factors) |
| qInv | CRT系数 (CRT Coefficient),一个小于p的正整数,满足: q * qInv == 1 (mod p) |
| r_i | RSA模数n的素因子,包括r_1 = p, r_2 = q以及其他额外因子(如果有) |
| s | 签名代表值 (Signature Representative),一个介于0和n-1之间的整数 |
| S | 签名 (Signature),一个八位字节串 |
| sLen | EMSA-PSS盐值 (Salt) 的长度(以八位字节为单位) |
| t_i | 额外素因子r_i的CRT系数,一个小于r_i的正整数,满足: r_1 * r_2 * ... * r_(i-1) * t_i == 1 (mod r_i), i = 3, ..., u |
| u | RSA模数的素因子数量, u >= 2 |
| x | 一个非负整数 |
| X | 对应于x的八位字节串 |
| xLen | 八位字节串X的(预期)长度 |
| 0x | 八位字节或八位字节串的十六进制表示指示符: "0x48"表示十六进制值为48的八位字节; "(0x)48 09 0e"表示由十六进制值分别为48、09和0e的三个连续八位字节组成的字符串 |
| λ(n) | LCM(r_1-1, r_2-1, ..., r_u-1) |
| ⊕ | 两个八位字节串的按位异或 (Bit-wise Exclusive-OR) |
| ⌈.⌉ | 上取整函数 (Ceiling Function); ⌈x⌉是大于或等于实数x的最小整数 |
| || | 连接运算符 (Concatenation Operator) |
| == | 同余符号 (Congruence Symbol); a == b (mod n)表示整数n能整除整数(a - b) |
注意: 中国剩余定理 (Chinese Remainder Theorem, CRT) 可以用非递归方式和递归方式应用. 在本文档中,使用遵循Garner算法 [GARNER] 的递归方法. 另请参见第3.2节中的注释1.
3. Key Types (密钥类型)
本文档定义的原语和方案中使用两种密钥类型: RSA公钥和RSA私钥. RSA公钥和RSA私钥一起构成RSA密钥对 (RSA Key Pair).
本规范支持所谓的"多素数" (Multi-prime) RSA,其中模数可以有两个以上的素因子. 多素数RSA的优势在于,如果使用中国剩余定理 (CRT),可以降低解密和签名原语的计算成本. 在单处理器平台上可以实现更好的性能,但在多处理器平台上可以达到更大程度的提升,因为涉及的模幂运算可以并行完成.
有关多素数如何影响RSA密码系统安全性的讨论,读者可参阅 [SILVERMAN].
3.1. RSA Public Key (RSA公钥)
对于本文档的目的,RSA公钥由两个组件组成:
n RSA模数 (RSA Modulus),一个正整数
e RSA公钥指数 (RSA Public Exponent),一个正整数
在有效的RSA公钥中,RSA模数n是u个不同奇素数r_i (i = 1, 2, ..., u,其中u >= 2)的乘积,RSA公钥指数e是介于3和n - 1之间的整数,满足 GCD(e, λ(n)) = 1,其中 λ(n) = LCM(r_1 - 1, ..., r_u - 1). 按照惯例,前两个素数r_1和r_2也可以分别表示为p和q.
附录A.1.1给出了在实现之间交换RSA公钥的推荐语法;实现的内部表示可能不同.
3.2. RSA Private Key (RSA私钥)
对于本文档的目的,RSA私钥可以有两种表示形式之一.
表示形式1
第一种表示形式由对 (n, d) 组成,其中组件具有以下含义:
n RSA模数 (RSA Modulus),一个正整数
d RSA私钥指数 (RSA Private Exponent),一个正整数
表示形式2
第二种表示形式由五元组 (p, q, dP, dQ, qInv) 和一个(可能为空的)三元组序列 (r_i, d_i, t_i) (i = 3, ..., u,对于五元组中未包含的每个素数各一个)组成,其中组件具有以下含义:
p 第一个因子,一个正整数
q 第二个因子,一个正整数
dP 第一个因子的CRT指数,一个正整数
dQ 第二个因子的CRT指数,一个正整数
qInv (第一个)CRT系数,一个正整数
r_i 第i个因子,一个正整数
d_i 第i个因子的CRT指数,一个正整数
t_i 第i个因子的CRT系数,一个正整数
有效性约束
在具有第一种表示形式的有效RSA私钥中,RSA模数n与相应RSA公钥中的相同,并且是u个不同奇素数r_i (i = 1, 2, ..., u,其中u >= 2)的乘积. RSA私钥指数d是小于n的正整数,满足:
e * d == 1 (mod λ(n))
其中e是相应的RSA公钥指数,λ(n)的定义如第3.1节所述.
在具有第二种表示形式的有效RSA私钥中,两个因子p和q是RSA模数n的前两个素因子(即r_1和r_2);CRT指数dP和dQ分别是小于p和q的正整数,满足:
e * dP == 1 (mod (p-1))
e * dQ == 1 (mod (q-1))
CRT系数qInv是小于p的正整数,满足:
q * qInv == 1 (mod p)
如果u > 2,该表示将包含一个或多个三元组 (r_i, d_i, t_i) (i = 3, ..., u). 因子r_i是RSA模数n的额外素因子. 每个CRT指数d_i (i = 3, ..., u)满足:
e * d_i == 1 (mod (r_i - 1))
每个CRT系数t_i (i = 3, ..., u)是小于r_i的正整数,满足:
R_i * t_i == 1 (mod r_i)
其中 R_i = r_1 * r_2 * ... * r_(i-1).
附录A.1.2给出了在实现之间交换RSA私钥的推荐语法,其中包含两种表示形式的组件;实现的内部表示可能不同.
注释
注释1: 这里CRT系数的定义以及第5节中原语使用它们的公式通常遵循Garner算法 [GARNER] (另请参见 [HANDBOOK] 中的算法14.71). 但是,为了与PKCS #1 v2.0及之前版本中RSA私钥表示的兼容性,与其余素数相比,p和q的角色是相反的. 因此,第一个CRT系数qInv定义为q mod p的逆,而不是R_1 mod r_2(即p mod q)的逆.
注释2: Quisquater和Couvreur [FASTDEC] 观察到将CRT应用于RSA操作的好处.
4. Data Conversion Primitives (数据转换原语)
本文档定义的方案中使用两个数据转换原语 (Data Conversion Primitives):
- I2OSP - 整数到八位字节串原语 (Integer-to-Octet-String Primitive)
- OS2IP - 八位字节串到整数原语 (Octet-String-to-Integer Primitive)
对于本文档的目的,并且与ASN.1语法一致,八位字节串 (Octet String) 是八位字节(8比特字节)的有序序列. 该序列从第一个(按惯例,最左边)到最后一个(最右边)进行索引. 为了与整数之间进行转换,在以下转换原语中,第一个八位字节被视为最高有效位.
4.1. I2OSP
I2OSP将非负整数转换为指定长度的八位字节串.
I2OSP (x, xLen)
输入 (Input)
x 要转换的非负整数
xLen 结果八位字节串的预期长度
输出 (Output)
X 长度为xLen的对应八位字节串
错误 (Error)
"integer too large" (整数过大)
步骤 (Steps)
步骤1. 如果 x >= 256^xLen,输出 "integer too large" 并停止.
步骤2. 将整数x写成其唯一的xLen位256进制表示:
x = x_(xLen-1) * 256^(xLen-1) + x_(xLen-2) * 256^(xLen-2) + ... + x_1 * 256 + x_0
其中 0 <= x_i < 256 (注意,如果x小于256^(xLen-1),一个或多个前导数字将为零).
步骤3. 令八位字节X_i的整数值为x_(xLen-i),其中 1 <= i <= xLen. 输出八位字节串:
X = X_1 X_2 ... X_xLen
4.2. OS2IP
OS2IP将八位字节串转换为非负整数.
OS2IP (X)
输入 (Input)
X 要转换的八位字节串
输出 (Output)
x 对应的非负整数
步骤 (Steps)
步骤1. 令 X_1 X_2 ... X_xLen 为X从第一个到最后一个的八位字节,令x_(xLen-i)为八位字节X_i的整数值,其中 1 <= i <= xLen.
步骤2. 令:
x = x_(xLen-1) * 256^(xLen-1) + x_(xLen-2) * 256^(xLen-2) + ... + x_1 * 256 + x_0
步骤3. 输出x.
5. Cryptographic Primitives (密码学原语)
密码学原语 (Cryptographic Primitives) 是可以构建密码学方案的基本数学运算. 它们旨在用硬件实现或作为软件模块,并且不打算脱离方案单独提供安全性.
本文档规定了四种类型的原语,成对组织: 加密和解密 (Encryption and Decryption); 签名和验证 (Signature and Verification).
原语的规范假设输入满足某些条件,特别是RSA公钥和私钥是有效的.
5.1. Encryption and Decryption Primitives (加密和解密原语)
加密原语 (Encryption Primitive) 在公钥的控制下从消息代表值生成密文代表值,解密原语 (Decryption Primitive) 在相应私钥的控制下从密文代表值恢复消息代表值.
本文档定义的加密方案中使用一对加密和解密原语,在此规定: RSA加密原语 (RSAEP, RSA Encryption Primitive) / RSA解密原语 (RSADP, RSA Decryption Primitive). RSAEP和RSADP涉及相同的数学运算,只是输入不同的密钥. 此处定义的原语与IEEE 1363 [IEEE1363] 中使用RSA的整数分解加密原语 (IFEP-RSA) / 使用RSA的整数分解解密原语 (IFDP-RSA) 相同(除了添加了对多素数RSA的支持),并且与PKCS #1 v1.5兼容.
每个原语中的主要数学运算是幂运算 (Exponentiation).
5.1.1. RSAEP
RSAEP ((n, e), m)
输入 (Input)
(n, e) RSA公钥
m 消息代表值,一个介于0和n - 1之间的整数
输出 (Output)
c 密文代表值,一个介于0和n - 1之间的整数
错误 (Error)
"message representative out of range" (消息代表值超出范围)
假设 (Assumption)
RSA公钥 (n, e) 是有效的
步骤 (Steps)
步骤1. 如果消息代表值m不在0和n - 1之间,输出 "message representative out of range" 并停止.
步骤2. 令 c = m^e mod n.
步骤3. 输出c.
5.1.2. RSADP
RSADP (K, c)
输入 (Input)
K RSA私钥,其中K具有以下形式之一:
- 对 (n, d)
- 五元组 (p, q, dP, dQ, qInv) 和可能为空的三元组序列 (r_i, d_i, t_i), i = 3, ..., u
c 密文代表值,一个介于0和n - 1之间的整数
输出 (Output)
m 消息代表值,一个介于0和n - 1之间的整数
错误 (Error)
"ciphertext representative out of range" (密文代表值超出范围)
假设 (Assumption)
RSA私钥K是有效的
步骤 (Steps)
步骤1. 如果密文代表值c不在0和n - 1之间,输出 "ciphertext representative out of range" 并停止.
步骤2. 消息代表值m按如下方式计算:
a. 如果使用K的第一种形式 (n, d),令 m = c^d mod n.
b. 如果使用K的第二种形式 (p, q, dP, dQ, qInv) 和 (r_i, d_i, t_i),按以下步骤进行:
i. 令 m_1 = c^dP mod p 且 m_2 = c^dQ mod q.
ii. 如果 u > 2,令 m_i = c^(d_i) mod r_i, i = 3, ..., u.
iii. 令 h = (m_1 - m_2) * qInv mod p.
iv. 令 m = m_2 + q * h.
v. 如果 u > 2,令 R = r_1 且对于 i = 3 到 u 执行:
- 令 R = R * r_(i-1).
- 令 h = (m_i - m) * t_i mod r_i.
- 令 m = m + R * h.
步骤3. 输出m.
注意: 步骤2.b可以重写为单个循环,前提是颠倒p和q的顺序. 然而,为了与PKCS #1 v2.0保持一致,前两个素数p和q与额外素数分开处理.
5.2. Signature and Verification Primitives (签名和验证原语)
签名原语 (Signature Primitive) 在私钥的控制下从消息代表值生成签名代表值,验证原语 (Verification Primitive) 在相应公钥的控制下从签名代表值恢复消息代表值. 本文档定义的签名方案中使用一对签名和验证原语,在此规定: RSA签名原语版本1 (RSASP1, RSA Signature Primitive, version 1) / RSA验证原语版本1 (RSAVP1, RSA Verification Primitive, version 1).
此处定义的原语与IEEE 1363 [IEEE1363] 中使用RSA的整数分解签名原语版本1 (IFSP-RSA1) / 使用RSA的整数分解验证原语版本1 (IFVP-RSA1) 相同(除了添加了对多素数RSA的支持),并且与PKCS #1 v1.5兼容.
每个原语中的主要数学运算是幂运算,与第5.1节的加密和解密原语相同. RSASP1和RSAVP1与RSADP和RSAEP相同,只是输入和输出参数的名称不同;它们之所以区分是因为它们用于不同的目的.
5.2.1. RSASP1
RSASP1 (K, m)
输入 (Input)
K RSA私钥,其中K具有以下形式之一:
- 对 (n, d)
- 五元组 (p, q, dP, dQ, qInv) 和(可能为空的)三元组序列 (r_i, d_i, t_i), i = 3, ..., u
m 消息代表值,一个介于0和n - 1之间的整数
输出 (Output)
s 签名代表值,一个介于0和n - 1之间的整数
错误 (Error)
"message representative out of range" (消息代表值超出范围)
假设 (Assumption)
RSA私钥K是有效的
步骤 (Steps)
步骤1. 如果消息代表值m不在0和n - 1之间,输出 "message representative out of range" 并停止.
步骤2. 签名代表值s按如下方式计算:
a. 如果使用K的第一种形式 (n, d),令 s = m^d mod n.
b. 如果使用K的第二种形式 (p, q, dP, dQ, qInv) 和 (r_i, d_i, t_i),按以下步骤进行:
- 令 s_1 = m^dP mod p 且 s_2 = m^dQ mod q.
- 如果 u > 2,令 s_i = m^(d_i) mod r_i, i = 3, ..., u.
- 令 h = (s_1 - s_2) * qInv mod p.
- 令 s = s_2 + q * h.
- 如果 u > 2,令 R = r_1 且对于 i = 3 到 u 执行:
- a. 令 R = R * r_(i-1).
- b. 令 h = (s_i - s) * t_i mod r_i.
- c. 令 s = s + R * h.
步骤3. 输出s.
注意: 步骤2.b可以重写为单个循环,前提是颠倒p和q的顺序. 然而,为了与PKCS #1 v2.0保持一致,前两个素数p和q与额外素数分开处理.
5.2.2. RSAVP1
RSAVP1 ((n, e), s)
输入 (Input)
(n, e) RSA公钥
s 签名代表值,一个介于0和n - 1之间的整数
输出 (Output)
m 消息代表值,一个介于0和n - 1之间的整数
错误 (Error)
"signature representative out of range" (签名代表值超出范围)
假设 (Assumption)
RSA公钥 (n, e) 是有效的
步骤 (Steps)
步骤1. 如果签名代表值s不在0和n - 1之间,输出 "signature representative out of range" 并停止.
步骤2. 令 m = s^e mod n.
步骤3. 输出m.
6. Overview of Schemes (方案概述)
方案 (Scheme) 将密码学原语和其他技术结合起来以实现特定的安全目标. 本文档规定了两种类型的方案: 加密方案 (Encryption Schemes) 和带附录的签名方案 (Signature Schemes with Appendix).
本文档规定的方案在范围上是有限的,因为它们的操作仅包含使用RSA公钥或私钥处理数据的步骤,不包括获取或验证密钥的步骤. 因此,除了方案操作之外,应用程序通常还会包括密钥管理操作 (Key Management Operations),通过这些操作,各方可以为方案操作选择RSA公钥和私钥. 具体的额外操作和其他详细信息超出了本文档的范围.
与密码学原语(第5节)的情况一样,方案操作的规范假设输入满足某些条件,特别是RSA公钥和私钥是有效的. 因此,当密钥无效时,实现的行为是未指定的. 这种未指定行为的影响取决于应用程序. 解决密钥验证问题的可能方法包括: 应用程序进行显式密钥验证; 在公钥基础设施内进行密钥验证; 以及将使用无效密钥执行操作的责任分配给生成密钥的一方.
一个普遍良好的密码学实践是仅在一个方案中使用给定的RSA密钥对. 这避免了一个方案中的漏洞可能损害另一个方案的安全性的风险,并且可能对于维护可证明的安全性 (Provable Security) 至关重要. 虽然RSAES-PKCS1-v1_5 (第7.2节) 和RSASSA-PKCS1-v1_5 (第8.2节) 传统上一起使用而没有任何已知的不良交互(实际上,这是PKCS #1 v1.5引入的模型),但对于新应用程序,不推荐 (NOT RECOMMENDED) 这种RSA密钥对的组合使用.
为了说明在多个方案中使用RSA密钥对的相关风险,假设RSA密钥对同时用于RSAES-OAEP (第7.1节) 和RSAES-PKCS1-v1_5. 尽管RSAES-OAEP本身可以抵抗攻击,但攻击者可能能够利用RSAES-PKCS1-v1_5实现中的弱点来恢复使用任一方案加密的消息. 另一个例子,假设RSA密钥对同时用于RSASSA-PSS (第8.1节) 和RSASSA-PKCS1-v1_5. 那么RSASSA-PSS的安全性证明将不再充分,因为该证明没有考虑可能使用第二个方案生成签名的可能性. 如果RSA密钥对用于此处定义的方案之一和在其他地方定义的变体,类似的考虑也可能适用.
7. Encryption Schemes (加密方案)
对于本文档的目的,加密方案 (Encryption Scheme) 由加密操作和解密操作组成,其中加密操作使用接收方的RSA公钥从消息生成密文,解密操作使用接收方相应的RSA私钥从密文恢复消息.
加密方案可以应用于多种应用场景. 一个典型的应用是密钥建立协议 (Key Establishment Protocol),其中消息包含需要从一方保密传递给另一方的密钥材料. 例如,PKCS #7 [RFC2315] 使用此类协议将内容加密密钥从发送方传递给接收方;本文档定义的加密方案适合在该上下文中作为密钥加密算法使用.
本文档规定了两种加密方案: RSAES-OAEP和RSAES-PKCS1-v1_5. 新应用程序必须 (REQUIRED) 支持RSAES-OAEP; RSAES-PKCS1-v1_5仅为了与现有应用程序兼容而包含.
此处给出的加密方案遵循与IEEE 1363 [IEEE1363] 中使用的类似的通用模型,将加密和解密原语与用于加密的编码方法相结合. 加密操作对消息应用消息编码操作以生成编码消息,然后将其转换为整数消息代表值. 将加密原语应用于消息代表值以生成密文. 反过来,解密操作将解密原语应用于密文以恢复消息代表值,然后将其转换为八位字节串编码消息. 将消息解码操作应用于编码消息以恢复消息并验证解密的正确性.
为了避免与解码操作中处理错误的方式相关的实现弱点(参见 [BLEICHENBACHER] 和 [MANGER]),RSAES-OAEP和RSAES-PKCS1-v1_5的编码和解码操作嵌入在各自加密方案的规范中,而不是在单独的规范中定义. 两种加密方案都与PKCS #1 v2.1中的相应方案兼容.
7.1. RSAES-OAEP
RSAES-OAEP结合了RSAEP和RSADP原语(第5.1节)与EME-OAEP编码方法(本节嵌入). 它基于 [OAEP] 中首次引入的Bellare和Rogaway的最优非对称加密填充 (Optimal Asymmetric Encryption Padding, OAEP) 方法. EME-OAEP是IEEE 1363 [IEEE1363] 中EME-OAEP的单向变体.
该方案不是确定性的:对于给定的公钥和消息,可以生成许多可能的密文.
RSAES-OAEP被推荐用于新应用. RSAES-OAEP可以作为任何应用程序中RSAES-PKCS1-v1_5的首选替代方案.
本方案的安全性基于两个函数的难度: RSA问题和掩码生成函数(Mask Generation Function, MGF)的随机预言模型. 两个函数的安全属性在定理证明中得到体现,该证明显示使用RSAES-OAEP对抗选择密文攻击 (Chosen Ciphertext Attack) 的难度与解决RSA问题的难度本质上一样困难,前提是MGF的行为类似于随机预言 (Random Oracle).
7.1.1. Encryption Operation (加密操作)
RSAES-OAEP-ENCRYPT ((n, e), M, L)
输入 (Input):
- (n, e): 接收方的RSA公钥 (k表示以八位字节为单位的模数长度)
- M: 要加密的消息,长度最多为k - 2hLen - 2的八位字节串,其中hLen是哈希函数Hash的输出长度(以八位字节为单位)
- L: 可选的与加密操作相关联的标签 (Label);默认值为空串
输出 (Output):
- C: 密文,长度为k的八位字节串
错误 (Errors):
- "message too long" (消息过长)
- "label too long" (标签过长)
假设 (Assumption): RSA公钥 (n, e) 是有效的
步骤 (Steps):
-
长度检查: 如果L的长度大于输入限制(对于掩码生成函数,该限制为2^61 - 1个八位字节),输出 "label too long" 并停止.
-
EME-OAEP编码:
- 如果M的长度大于k - 2hLen - 2个八位字节,输出 "message too long" 并停止.
- 令lHash = Hash(L),长度为hLen的八位字节串.
- 生成由k - mLen - 2hLen - 2个零八位字节和单个值为0x01的八位字节组成的填充串PS.
- 连接lHash, PS, 0x01单字节和消息M形成数据块DB: DB = lHash || PS || 0x01 || M
- 生成长度为hLen的随机八位字节串seed.
- 令dbMask = MGF(seed, k - hLen - 1).
- 令maskedDB = DB ⊕ dbMask.
- 令seedMask = MGF(maskedDB, hLen).
- 令maskedSeed = seed ⊕ seedMask.
- 连接单个值为0x00的八位字节、maskedSeed和maskedDB形成编码消息EM: EM = 0x00 || maskedSeed || maskedDB
-
RSA加密:
- 将编码消息EM转换为整数消息代表值m: m = OS2IP(EM)
- 应用RSAEP加密原语: c = RSAEP((n, e), m)
- 将密文代表值c转换为长度为k的密文C: C = I2OSP(c, k)
-
输出密文C.
7.1.2. Decryption Operation (解密操作)
RSAES-OAEP-DECRYPT (K, C, L)
输入 (Input):
- K: 接收方的RSA私钥
- C: 要解密的密文,长度为k的八位字节串,其中k是RSA模数n的长度(以八位字节为单位)
- L: 可选标签,其值与加密操作期间生成密文时的标签相关联;默认值为空串
输出 (Output):
- M: 消息,长度最多为k - 2hLen - 2的八位字节串
错误 (Error):
- "decryption error" (解密错误)
步骤 (Steps):
-
长度检查: 如果L的长度大于输入限制,输出 "decryption error" 并停止. 如果密文C的长度不是k个八位字节(或k < 2hLen + 2),输出 "decryption error" 并停止.
-
RSA解密:
- 将密文C转换为整数密文代表值c: c = OS2IP(C)
- 应用RSADP解密原语: m = RSADP(K, c). 如果RSADP输出 "ciphertext representative out of range",输出 "decryption error" 并停止.
- 将消息代表值m转换为长度为k的编码消息EM: EM = I2OSP(m, k)
-
EME-OAEP解码:
- 令lHash = Hash(L).
- 将EM分离为单个八位字节Y、长度为hLen的八位字节串maskedSeed和长度为k - hLen - 1的八位字节串maskedDB: EM = Y || maskedSeed || maskedDB
- 令seedMask = MGF(maskedDB, hLen).
- 令seed = maskedSeed ⊕ seedMask.
- 令dbMask = MGF(seed, k - hLen - 1).
- 令DB = maskedDB ⊕ dbMask.
- 将DB分离为长度为hLen的八位字节串lHash'、(可能为空的)填充串PS(由值为0x00的八位字节组成)、单个值为0x01的八位字节和消息M: DB = lHash' || PS || 0x01 || M. 如果没有值为0x01的八位字节来分隔PS和M,如果lHash不等于lHash',或如果Y非零,则输出 "decryption error" 并停止.
-
输出消息M.
注意: 应谨慎实现,以避免实现无意中向对手提供有用信息. 特别是,错误消息不应透露EM中的八位字节或DB中的其他八位字节是否不是预期形式.
7.2. RSAES-PKCS1-v1_5
RSAES-PKCS1-v1_5结合了RSAEP和RSADP原语(第5.1节)与EME-PKCS1-v1_5编码方法. 它被包含仅是为了与现有应用程序兼容;对于新应用程序,推荐使用RSAES-OAEP.
RSAES-PKCS1-v1_5的安全性依赖于RSA问题的难度. 已知可能的弱点(参见[BLEICHENBACHER]),因此新应用程序应使用RSAES-OAEP.
7.2.1. Encryption Operation (加密操作)
RSAES-PKCS1-V1_5-ENCRYPT ((n, e), M)
输入、输出和步骤与RSAES-OAEP类似,但使用EME-PKCS1-v1_5编码
7.2.2. Decryption Operation (解密操作)
RSAES-PKCS1-V1_5-DECRYPT (K, C)
输入、输出和步骤与RSAES-OAEP类似,但使用EME-PKCS1-v1_5解码
重要安全注意事项: 解密错误消息不应区分不同类型的错误,以防止 Bleichenbacher 选择密文攻击.
8. Signature Scheme with Appendix (带附录的签名方案)
带附录的签名方案 (Signature Scheme with Appendix) 由签名生成操作和签名验证操作组成,其中签名生成操作使用签名者的RSA私钥从消息生成签名,签名验证操作使用签名者的RSA公钥验证签名的真实性.
为了签署消息M,签名者对M应用消息编码操作以生成编码消息EM,然后应用签名原语产生签名S. 为了验证签名S,验证者对S应用验证原语以恢复编码消息EM,然后应用验证操作以确定签名是否对消息有效.
两种签名方案在本文档中规定: RSASSA-PSS和RSASSA-PKCS1-v1_5.
虽然不强制,但RSASSA-PSS推荐用于新应用. RSASSA-PKCS1-v1_5包含是为了与现有应用程序兼容.
8.1. RSASSA-PSS
RSASSA-PSS结合了RSASP1和RSAVP1原语(第5.2节)与EMSA-PSS编码方法. 它基于Bellare和Rogaway提出的概率签名方案 (Probabilistic Signature Scheme, PSS) [RSARABIN] [PSS].
PSS的安全性基于RSA问题的难度和MGF的随机预言模型. 已证明在随机预言模型下,如果MGF行为类似于随机预言且RSA问题是困难的,那么PSS签名方案对于选择消息攻击 (Chosen Message Attack) 是安全的.
RSASSA-PSS不是确定性的:对于给定的消息,可以生成多个可能的签名. 这是因为签名生成操作期间包含了随机盐值.
8.1.1. Signature Generation Operation (签名生成操作)
RSASSA-PSS-SIGN (K, M)
输入 (Input):
- K: 签名者的RSA私钥
- M: 要签名的消息,长度为任意的八位字节串
输出 (Output):
- S: 签名,长度为k的八位字节串,其中k是RSA模数n的长度(以八位字节为单位)
错误 (Errors):
- "message too long" (消息过长)
- "encoding error" (编码错误)
步骤 (Steps):
-
EMSA-PSS编码: 对消息M应用EMSA-PSS编码操作以生成长度为⌈(modBits-1)/8⌉个八位字节的编码消息EM,其中modBits是RSA模数n的长度(以比特为单位): EM = EMSA-PSS-ENCODE(M, modBits - 1). 如果编码操作输出 "message too long" 或 "encoding error",输出相应错误并停止.
-
RSA签名:
- 将编码消息EM转换为整数消息代表值m: m = OS2IP(EM)
- 应用RSASP1签名原语: s = RSASP1(K, m)
- 将签名代表值s转换为长度为k的签名S: S = I2OSP(s, k)
-
输出签名S.
8.1.2. Signature Verification Operation (签名验证操作)
RSASSA-PSS-VERIFY ((n, e), M, S)
输入 (Input):
- (n, e): 签名者的RSA公钥
- M: 消息,长度为任意的八位字节串
- S: 要验证的签名,长度为k的八位字节串
输出 (Output):
- "valid signature" (有效签名) 或 "invalid signature" (无效签名)
步骤 (Steps):
-
长度检查: 如果签名S的长度不是k个八位字节,输出 "invalid signature" 并停止.
-
RSA验证:
- 将签名S转换为整数签名代表值s: s = OS2IP(S)
- 应用RSAVP1验证原语: m = RSAVP1((n, e), s). 如果RSAVP1输出 "signature representative out of range",输出 "invalid signature" 并停止.
- 将消息代表值m转换为长度为emLen = ⌈(modBits - 1)/8⌉的编码消息EM: EM = I2OSP(m, emLen)
-
EMSA-PSS验证: 应用EMSA-PSS验证操作: Result = EMSA-PSS-VERIFY(M, EM, modBits - 1). 如果Result = "consistent",输出 "valid signature"; 否则输出 "invalid signature".
8.2. RSASSA-PKCS1-v1_5
RSASSA-PKCS1-v1_5结合了RSASP1和RSAVP1原语(第5.2节)与EMSA-PKCS1-v1_5编码方法. 它与IEEE 1363 [IEEE1363] 中的IFSSA方案兼容,其中使用DigestInfo值的哈希函数来生成消息代表值.
RSASSA-PKCS1-v1_5的安全性依赖于RSA问题的难度. 虽然没有已知的攻击成功破解该方案,但也没有像PSS那样的安全性证明.
8.2.1. Signature Generation Operation (签名生成操作)
RSASSA-PKCS1-V1_5-SIGN (K, M)
步骤与RSASSA-PSS类似,但使用EMSA-PKCS1-v1_5编码方法
8.2.2. Signature Verification Operation (签名验证操作)
RSASSA-PKCS1-V1_5-VERIFY ((n, e), M, S)
步骤与RSASSA-PSS类似,但使用EMSA-PKCS1-v1_5验证方法
9. Encoding Methods for Signatures with Appendix (带附录签名的编码方法)
编码方法用于将消息转换为编码消息,编码消息随后可以通过RSA签名原语进行签名. 本节规定了两种编码方法: EMSA-PSS和EMSA-PKCS1-v1_5.
9.1. EMSA-PSS
EMSA-PSS (Encoding Method for Signatures with Appendix - Probabilistic Signature Scheme) 是一种概率编码方法,包含随机性,因此对于给定的消息可以生成多个不同的编码消息.
9.1.1. Encoding Operation (编码操作)
EMSA-PSS-ENCODE (M, emBits)
输入 (Input):
- M: 要编码的消息,长度为任意的八位字节串
- emBits: 编码消息的最大比特长度,至少为8hLen + 8sLen + 9
输出 (Output):
- EM: 编码消息,长度为emLen = ⌈emBits/8⌉的八位字节串
步骤 (Steps):
-
如果M的长度大于哈希函数Hash的输入限制(2^61 - 1个八位字节对于SHA-1),输出 "message too long" 并停止.
-
令mHash = Hash(M),长度为hLen的八位字节串.
-
如果emLen < hLen + sLen + 2,输出 "encoding error" 并停止.
-
生成长度为sLen的随机八位字节串salt.
-
令M' = (0x)00 00 00 00 00 00 00 00 || mHash || salt; M'是长度为8 + hLen + sLen的八位字节串.
-
令H = Hash(M'),长度为hLen的八位字节串.
-
生成由emLen - sLen - hLen - 2个零八位字节组成的八位字节串PS.
-
令DB = PS || 0x01 || salt; DB是长度为emLen - hLen - 1的八位字节串.
-
令dbMask = MGF(H, emLen - hLen - 1).
-
令maskedDB = DB ⊕ dbMask.
-
将maskedDB的最左边8emLen - emBits位设置为零.
-
令EM = maskedDB || H || 0xbc.
-
输出EM.
9.1.2. Verification Operation (验证操作)
EMSA-PSS-VERIFY (M, EM, emBits)
输入 (Input):
- M: 消息,长度为任意的八位字节串
- EM: 要验证的编码消息,长度为emLen = ⌈emBits/8⌉的八位字节串
- emBits: 编码消息的最大比特长度
输出 (Output):
- "consistent" (一致) 或 "inconsistent" (不一致)
步骤: (验证步骤与编码步骤相反,检查所有约束)
9.2. EMSA-PKCS1-v1_5
EMSA-PKCS1-v1_5 (Encoding Method for Signatures with Appendix - PKCS #1 v1.5) 是一种确定性编码方法,对于给定的消息总是生成相同的编码消息.
EMSA-PKCS1-v1_5-ENCODE (M, emLen)
输入 (Input):
- M: 要编码的消息,长度为任意的八位字节串
- emLen: 编码消息的预期长度(以八位字节为单位),至少为tLen + 11,其中tLen是DigestInfo值的八位字节长度
输出 (Output):
- EM: 编码消息,长度为emLen的八位字节串
步骤 (Steps):
-
对消息M应用哈希函数以生成哈希值H: H = Hash(M). 如果哈希函数输出 "message too long",输出 "message too long" 并停止.
-
使用第9.2节注释中的技术,将DigestInfo值编码为T,用于哈希函数.
-
如果emLen < tLen + 11,输出 "intended encoded message length too short" 并停止.
-
生成由emLen - tLen - 3个值为0xff的八位字节组成的八位字节串PS.
-
连接PS和其他填充以形成编码消息EM: EM = 0x00 || 0x01 || PS || 0x00 || T
-
输出EM.
10. Security Considerations (安全考虑)
本文档中已在各处讨论了安全考虑事项.
主要安全要点
密钥长度
RSA密钥的安全性高度依赖于模数的大小. 推荐的最小密钥长度:
- 2048位: 当前最低推荐长度
- 3072位: 高安全应用推荐
- 4096位: 长期密钥或极高安全要求
方案选择
- RSAES-OAEP: 新应用的加密方案必须 (REQUIRED) 支持
- RSASSA-PSS: 新应用推荐 (RECOMMENDED) 使用的签名方案
- PKCS1-v1_5: 仅为兼容性保留,存在已知弱点
实现注意事项
- 随机数生成: 必须使用密码学安全的随机数生成器
- 侧信道攻击: 实现应防止时序攻击和功耗分析
- 错误处理: 解密和验证操作的错误消息应统一,避免泄露信息
- 填充预言攻击: RSAES-PKCS1-v1_5易受Bleichenbacher攻击,实现时需特别小心
哈希函数
- 避免使用: MD5, SHA-1(已被破解)
- 推荐使用: SHA-256, SHA-384, SHA-512
密钥使用
- 单一用途: 一个RSA密钥对应该只用于一种方案(加密或签名,不混用)
- 密钥轮换: 定期更换密钥
- 私钥保护: 私钥应加密存储,使用硬件安全模块 (HSM) 是最佳实践
已知攻击和防御
- 选择密文攻击 (Chosen Ciphertext Attack): RSAES-OAEP提供防护
- 选择消息攻击 (Chosen Message Attack): RSASSA-PSS提供防护
- Bleichenbacher攻击: 影响RSAES-PKCS1-v1_5
- 时序攻击: 使用常数时间算法和CRT加速时需注意
参考第6节关于避免在多个方案中使用同一密钥对的讨论.
Appendix A. ASN.1 Syntax (ASN.1语法)
本附录总结了本文档中使用的ASN.1语法. 附录C包含完整的ASN.1模块.
A.1. RSA Key Representation (RSA密钥表示)
本节定义RSA公钥和私钥的ASN.1语法.
A.1.1. RSA Public Key Syntax (RSA公钥语法)
RSA公钥应表示为ASN.1类型RSAPublicKey:
RSAPublicKey ::= SEQUENCE {
modulus INTEGER, -- n
publicExponent INTEGER -- e
}
字段说明:
- modulus: RSA模数n
- publicExponent: RSA公钥指数e
在有效的RSA公钥中,模数n的值应该是u个不同奇素数r_i (i = 1, 2, ..., u)的乘积,其中u >= 2,公钥指数e应该是介于3和n - 1之间的整数,满足GCD(e, λ(n)) = 1.
A.1.2. RSA Private Key Syntax (RSA私钥语法)
RSA私钥应表示为ASN.1类型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
}
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, -- r_i
exponent INTEGER, -- d_i
coefficient INTEGER -- t_i
}
字段说明:
- version: 版本号 (two-prime表示两素数RSA,multi表示多素数RSA)
- modulus: RSA模数n
- publicExponent: RSA公钥指数e
- privateExponent: RSA私钥指数d
- prime1: 第一个素因子p
- prime2: 第二个素因子q
- exponent1: d mod (p-1)
- exponent2: d mod (q-1)
- coefficient: CRT系数qInv, (q^-1) mod p
- otherPrimeInfos: 可选,用于多素数RSA的额外素因子信息
A.2. Scheme Identification (方案标识)
本节定义本文档中定义的各种方案的对象标识符 (Object Identifiers).
A.2.1. RSAES-OAEP
RSAES-OAEP加密方案的对象标识符为:
id-RSAES-OAEP OBJECT IDENTIFIER ::= { pkcs-1 7 }
RSAES-OAEP的算法参数类型为:
RSAES-OAEP-params ::= SEQUENCE {
hashFunc [0] AlgorithmIdentifier DEFAULT sha1,
maskGenFunc [1] AlgorithmIdentifier DEFAULT mgf1SHA1,
pSourceFunc [2] AlgorithmIdentifier DEFAULT pSpecifiedEmpty
}
A.2.2. RSAES-PKCS1-v1_5
RSAES-PKCS1-v1_5加密方案的对象标识符为:
id-RSAES-PKCS1-v1_5 OBJECT IDENTIFIER ::= { pkcs-1 1 }
该方案没有关联的参数.
A.2.3. RSASSA-PSS
RSASSA-PSS签名方案的对象标识符为:
id-RSASSA-PSS OBJECT IDENTIFIER ::= { pkcs-1 10 }
RSASSA-PSS的算法参数类型为:
RSASSA-PSS-params ::= SEQUENCE {
hashAlgorithm [0] AlgorithmIdentifier DEFAULT sha1,
maskGenAlgorithm [1] AlgorithmIdentifier DEFAULT mgf1SHA1,
saltLength [2] INTEGER DEFAULT 20,
trailerField [3] INTEGER DEFAULT 1
}
A.2.4. RSASSA-PKCS1-v1_5
RSASSA-PKCS1-v1_5签名方案使用以下对象标识符用于不同的哈希函数:
sha256WithRSAEncryption OBJECT IDENTIFIER ::= { pkcs-1 11 }
sha384WithRSAEncryption OBJECT IDENTIFIER ::= { pkcs-1 12 }
sha512WithRSAEncryption OBJECT IDENTIFIER ::= { pkcs-1 13 }
这些对象标识符与特定的哈希函数关联.
Appendix B. Supporting Techniques (支持技术)
本附录包含本文档中使用的支持技术的规范,包括哈希函数和掩码生成函数.
B.1. Hash Functions (哈希函数)
哈希函数用于将任意长度的消息映射到固定长度的输出. 本文档的方案中使用的哈希函数应满足以下属性:
- 抗原像性 (Preimage Resistance): 给定哈希值h,在计算上不可行找到消息m使得Hash(m) = h
- 抗第二原像性 (Second Preimage Resistance): 给定消息m1,在计算上不可行找到不同的消息m2使得Hash(m1) = Hash(m2)
- 抗碰撞性 (Collision Resistance): 在计算上不可行找到任意两个不同的消息m1和m2使得Hash(m1) = Hash(m2)
推荐的哈希函数
本文档推荐使用以下哈希函数:
| 哈希函数 | 输出长度(比特) | 输出长度(字节) | 状态 |
|---|---|---|---|
| SHA-1 | 160 | 20 | ⚠️ 已废弃(仅向后兼容) |
| SHA-256 | 256 | 32 | ✅ 推荐 |
| SHA-384 | 384 | 48 | ✅ 推荐 |
| SHA-512 | 512 | 64 | ✅ 推荐 |
| SHA-512/224 | 224 | 28 | ✅ 可用 |
| SHA-512/256 | 256 | 32 | ✅ 可用 |
哈希函数的ASN.1标识
SHA-256的算法标识符:
id-sha256 OBJECT IDENTIFIER ::= {
joint-iso-itu-t(2) country(16) us(840) organization(1)
gov(101) csor(3) nistalgorithm(4) hashalgs(2) 1
}
SHA-384的算法标识符:
id-sha384 OBJECT IDENTIFIER ::= {
joint-iso-itu-t(2) country(16) us(840) organization(1)
gov(101) csor(3) nistalgorithm(4) hashalgs(2) 2
}
SHA-512的算法标识符:
id-sha512 OBJECT IDENTIFIER ::= {
joint-iso-itu-t(2) country(16) us(840) organization(1)
gov(101) csor(3) nistalgorithm(4) hashalgs(2) 3
}
B.2. Mask Generation Functions (掩码生成函数)
掩码生成函数 (Mask Generation Function, MGF) 接受可变长度的八位字节串和所需的输出长度作为输入,生成指定长度的输出八位字节串. 掩码生成函数可能基于哈希函数或其他函数.
掩码生成函数的主要用途是在填充方案中生成随机外观的数据.
B.2.1. MGF1
MGF1是一种基于哈希函数的掩码生成函数. MGF1 (mgfSeed, maskLen)接受一个可变长度的种子和所需的掩码长度作为输入,并输出指定长度的掩码.
MGF1 (mgfSeed, maskLen)
输入 (Input)
mgfSeed 掩码生成种子,长度为任意的八位字节串
maskLen 预期掩码的长度(以八位字节为单位)
输出 (Output)
mask 长度为maskLen的掩码,八位字节串
错误 (Error)
"mask too long" (掩码过长)
步骤 (Steps)
-
如果maskLen > 2^32 * hLen,输出 "mask too long" 并停止.
-
令T为空八位字节串.
-
对于从0到⌈maskLen / hLen⌉ - 1的计数器C:
- 将计数器C转换为长度为4的八位字节串C: C = I2OSP(C, 4)
- 连接mgfSeed和C的哈希值到T: T = T || Hash(mgfSeed || C)
-
输出T的前maskLen个八位字节作为掩码.
MGF1选项 (MGF1 Options)
MGF1的默认哈希函数是SHA-1. 对于新应用,推荐使用SHA-256或更高的哈希函数.
MGF1与SHA-256的ASN.1标识:
id-mgf1 OBJECT IDENTIFIER ::= { pkcs-1 8 }
-- MGF1的参数是使用的哈希函数
AlgorithmIdentifier { ALGORITHM:IOSet } ::= SEQUENCE {
algorithm ALGORITHM.&id({IOSet}),
parameters ALGORITHM.&Type({IOSet}{@algorithm}) OPTIONAL
}
MGF的安全考虑
在随机预言模型下,如果基础哈希函数表现良好,MGF1的输出在计算上与真正的随机串不可区分. 这使得MGF1适合在OAEP和PSS等方案中使用.
Appendix D. Revision History of PKCS #1 (PKCS #1修订历史)
版本演进
PKCS #1 v1.5 (1993年11月)
- 内容: 定义了RSA加密和签名的基本方案
- 加密: RSAES-PKCS1-v1_5
- 签名: RSASSA-PKCS1-v1_5
- 状态: 广泛部署,但存在已知安全弱点
PKCS #1 v2.0 (1998年9月, RFC 2437)
- 新增: RSAES-OAEP加密方案
- 新增: RSASSA-PSS签名方案
- 改进: 引入基于证明的安全方案
- 保留: v1.5方案以保持向后兼容
PKCS #1 v2.1 (2002年6月, RFC 3447)
- 改进: 更新RSAES-OAEP和RSASSA-PSS规范
- 新增: 支持额外的哈希函数(SHA-256, SHA-384, SHA-512)
- 新增: 完整的ASN.1模块
- 澄清: 多素数RSA的使用
PKCS #1 v2.2 (2012年10月 / 2016年11月, RFC 8017)
- 改进: 技术澄清和勘误修正
- 更新: 对安全考虑的增强描述
- 新增: 对SHA-512/224和SHA-512/256的支持
- 状态: 当前版本,作为RFC 8017发布
主要变更总结
- v1.5 → v2.0: 引入可证明安全的OAEP和PSS方案
- v2.0 → v2.1: 增强哈希函数支持和多素数RSA
- v2.1 → v2.2: 技术澄清和安全建议更新
- RFC转移: 从RSA实验室的PKCS系列转移到IETF RFC系列
废弃说明
- RFC 3447 (PKCS #1 v2.1) 被本文档 (RFC 8017, PKCS #1 v2.2) 废弃
- RSAES-PKCS1-v1_5 仅为向后兼容保留,不推荐新应用使用
- SHA-1 由于已知的碰撞攻击,不再推荐使用
兼容性注意事项
虽然各版本间引入了新方案,但为了向后兼容性:
- v1.5方案在所有版本中保持支持
- 新增的方案(OAEP, PSS)与旧实现共存
- ASN.1语法保持向后兼容
Appendix E. About PKCS (关于PKCS)
关于公钥密码学标准 (Public-Key Cryptography Standards)
公钥密码学标准 (PKCS, Public-Key Cryptography Standards) 是由RSA实验室与来自工业界和学术界的开发者合作制定的规范,旨在加速公钥密码学技术的部署.
PKCS系列概述
PKCS系列最初由RSA Security Inc. (前身为RSA Data Security, Inc.)发起,包含多个标准:
| 标准 | 名称 | 状态 |
|---|---|---|
| PKCS #1 | RSA密码学规范 | ✅ 本文档 (RFC 8017) |
| PKCS #3 | Diffie-Hellman密钥协商标准 | - |
| PKCS #5 | 基于口令的密码学规范 | RFC 2898, RFC 8018 |
| PKCS #6 | 扩展证书语法标准 | 已废弃 |
| PKCS #7 | 密码学消息语法标准 | RFC 2315 (被CMS取代) |
| PKCS #8 | 私钥信息语法规范 | RFC 5208, RFC 5958 |
| PKCS #9 | 选定属性类型 | RFC 2985 |
| PKCS #10 | 证书请求语法规范 | RFC 2986 |
| PKCS #11 | 密码学令牌接口 (Cryptoki) | OASIS标准 |
| PKCS #12 | 个人信息交换语法标准 | RFC 7292 |
| PKCS #15 | 密码学令牌信息格式标准 | ISO/IEC 7816-15 |
PKCS #1的历史意义
PKCS #1是PKCS系列中最早和最重要的标准之一,定义了RSA密码学的标准化实现方式:
- 工业采用: PKCS #1被广泛采用于SSL/TLS, SSH, S/MIME, PGP等协议
- 标准化影响: 影响了IEEE 1363, ISO/IEC 18033等国际标准
- 学术贡献: OAEP和PSS方案的引入推动了可证明安全密码学的发展
从RSA实验室到IETF
2000年代中期开始,PKCS系列标准逐渐转移到开放标准组织:
- IETF: PKCS #1, #5, #7, #8, #9, #10, #12转为RFC
- OASIS: PKCS #11 (Cryptoki)转为OASIS标准
- ISO/IEC: PKCS #15整合进ISO/IEC 7816标准
本文档 (RFC 8017) 代表PKCS #1的控制权从RSA实验室转移到IETF,确保该标准的持续维护和演进.
致谢 (Acknowledgements)
PKCS #1的发展得益于来自密码学社区的众多贡献,包括:
- 原始作者: Burt Kaliski, Jake Lacy
- 理论基础: Mihir Bellare, Phillip Rogaway (OAEP和PSS方案)
- v2.0-v2.2贡献者: Jakob Jonsson, Burt Kaliski, Kathleen Moriarty, Andreas Rusch
- 审阅和反馈: 来自IETF社区、RSA实验室和学术界的广泛审查
更多信息
- IETF PKCS工作组: ````https://datatracker.ietf.org/wg/pkcs/\````
- RSA实验室: ````http://www.rsa.com/rsalabs/\````
- PKCS存档: ````https://www.emc.com/emc-plus/rsa-labs/standards-initiatives/pkcs.htm\````