非官方中文译本声明:本页为 IETF RFC 8551《Secure/Multipurpose Internet Mail Extensions (S/MIME) Version 4.0 Message Specification》(S/MIME v4 证书处理) 的中文译本,由 ztpop.net 整理翻译,仅供学习参考。RFC 文档由 IETF 发布,受 BCP 78 与 IETF 信托法律条款约束;本译本保留原文编号与结构,权威性以英文原文为准。英文原文见 rfc-editor.org/rfc/rfc8551。
RFC 8551:S/MIME v4 证书处理
摘要
本文档定义了安全/多用途 Internet 邮件扩展(S/MIME)版本 4.0。S/MIME 提供了一种一致的方式来发送和接收安全的 MIME 数据。数字签名提供认证、消息完整性和带有起源证明的不可否认性。加密提供数据机密性。压缩可用于减小数据大小。本文档废弃了 RFC 5751。
本备忘录的状态
这是一份 Internet 标准跟踪文档。
本文档是 Internet 工程任务组(IETF)的成果。它代表 IETF 社区的共识,已经过公开评审,并由 Internet 工程指导组(IESG)批准发布。关于 Internet 标准的更多信息见 RFC 7841 第 2 节。
关于本文档当前状态、任何勘误以及如何提供反馈的信息,可在 https://www.rfc-editor.org/info/rfc8551 获取。
版权声明
Copyright (c) 2019 IETF 信托及被列为文档作者的个人。保留所有权利。
本文档受 BCP 78 以及 IETF 信托的《IETF 文档相关法律规定》(https://trustee.ietf.org/license-info)约束,以本文档发布之日生效的版本为准。请仔细审阅这些文档,因为它们描述了您就本文档所享有的权利与限制。从严本档提取的代码组件必须包含《简化 BSD 许可证》文本(如信托法律条款第 4.e 节所述),并按该许可证的描述不提供担保地提供。
本文档可能包含 2008 年 11 月 10 日之前发布或公开提供的 IETF 文档或 IETF 贡献中的材料。控制其中部分材料版权的个人或实体可能未授予 IETF 信托在 IETF 标准流程之外修改此类材料的权利。除非从控制此类材料版权的个人或实体获得适当的许可,否则本文档不得在 IETF 标准流程之外被修改,也不得在 IETF 标准流程之外创建其衍生作品,但将其格式化为 RFC 发布或将其翻译为英语以外的语言除外。
目录
- 1. 引言
- 1.1. 规范概述
- 1.2. 定义
- 1.3. 本文档使用的约定
- 1.4. 与 S/MIME 既有实践的兼容性
- 1.5. 从 S/MIME v3 到 S/MIME v3.1 的变更
- 1.6. 从 S/MIME v3.1 到 S/MIME v3.2 的变更
- 1.7. S/MIME v4.0 的变更
- 2. CMS 选项
- 2.1. DigestAlgorithmIdentifier
- 2.2. SignatureAlgorithmIdentifier
- 2.3. KeyEncryptionAlgorithmIdentifier
- 2.4. 通用语法
- 2.4.1. Data 内容类型
- 2.4.2. SignedData 内容类型
- 2.4.3. EnvelopedData 内容类型
- 2.4.4. AuthEnvelopedData 内容类型
- 2.4.5. CompressedData 内容类型
- 2.5. 属性与 SignerInfo 类型
- 2.5.1. 签名时间属性
- 2.5.2. SMIMECapabilities 属性
- 2.5.3. 加密密钥偏好属性
- 2.5.3.1. 收件人密钥管理证书的选择
- 2.6. SignerIdentifier SignerInfo 类型
- 2.7. ContentEncryptionAlgorithmIdentifier
- 2.7.1. 决定使用哪种加密方法
- 2.7.1.1. 规则 1:已知能力
- 2.7.1.2. 规则 2:未知能力、未知 S/MIME 版本
- 2.7.2. 选择弱加密
- 2.7.3. 多个收件人
- 2.7.1. 决定使用哪种加密方法
- 3. 创建 S/MIME 消息
- 3.1. 为签名、封装或压缩准备 MIME 实体
- 3.1.1. 规范化
- 3.1.2. 传输编码
- 3.1.3. 使用 multipart/signed 签名的传输编码
- 3.1.4. 规范化 MIME 实体示例
- 3.2. application/pkcs7-mime 媒体类型
- 3.2.1. name 与 filename 参数
- 3.2.2. smime-type 参数
- 3.3. 创建纯封装消息
- 3.4. 创建纯认证封装消息
- 3.5. 创建纯签名消息
- 3.5.1. 为纯签名消息选择格式
- 3.5.2. 使用 application/pkcs7-mime 与 SignedData 签名
- 3.5.3. 使用 multipart/signed 格式签名
- 3.5.3.1. application/pkcs7-signature 媒体类型
- 3.5.3.2. 创建 multipart/signed 消息
- 3.5.3.3. multipart/signed 消息示例
- 3.6. 创建纯压缩消息
- 3.7. 多重操作
- 3.8. 创建证书管理消息
- 3.9. 注册请求
- 3.10. 识别 S/MIME 消息
- 3.1. 为签名、封装或压缩准备 MIME 实体
- 4. 证书处理
- 4.1. 密钥对生成
- 4.2. 签名生成
- 4.3. 签名验证
- 4.4. 加密
- 4.5. 解密
- 5. IANA 考量
- 5.1. application/pkcs7-mime 的媒体类型
- 5.2. application/pkcs7-signature 的媒体类型
- 5.3. authEnveloped-data smime-type
- 5.4. 参考更新
- 6. 安全考量
- 7. 参考文献
- 7.1. 参考约定
- 7.2. 规范性参考文献
- 7.3. 资料性参考文献
- 附录 A. ASN.1 模块
- 附录 B. 历史邮件考量
- B.1. DigestAlgorithmIdentifier
- B.2. 签名算法
- B.3. ContentEncryptionAlgorithmIdentifier
- B.4. KeyEncryptionAlgorithmIdentifier
- 附录 C. 将 S/MIME v2 消息规范移至历史状态
- 致谢
- 作者地址
1. 引言
S/MIME(安全/多用途 Internet 邮件扩展)提供了一种一致的方式来发送和接收安全的 MIME 数据。基于流行的 Internet MIME 标准,S/MIME 为电子邮件消息应用提供以下密码学安全服务:认证、消息完整性、以及起源不可否认性(使用数字签名),以及数据机密性(使用加密)。作为一种辅助服务,S/MIME 提供消息压缩。
S/MIME 可由传统邮件用户代理(MUA)用来为所发送的邮件添加密码学安全服务,并解释所接收邮件中的密码学安全服务。然而,S/MIME 并不局限于邮件;它可用于任何传输 MIME 数据的传输机制,例如 HTTP 或 SIP。因此,S/MIME 利用 MIME 的基于对象的特性,并允许安全消息在混合传输系统中交换。
此外,S/MIME 可用于自动化的消息传输代理,这些代理使用不需要任何人工干预的密码学安全服务,例如对软件生成文档的签名,以及对经由 Internet 发送的传真消息的加密。
本文档定义了 S/MIME 消息规范的第 4.0 版。因此,本文档废弃了 S/MIME 消息规范的第 3.2 版 [RFC5751]。
本规范包含若干对被废弃或替换的文档的引用。这是有意为之,因为更新后的文档通常不再包含相同的信息或协议要求。
1.1. 规范概述
本文档描述了一种向 MIME 数据添加密码学签名和加密服务的协议。MIME 标准 [MIME-SPEC] 为 Internet 消息内容提供了通用结构,并允许基于内容类型的新应用扩展。
本规范定义了如何创建根据密码消息语法(CMS)[CMS](派生自 PKCS #7 [RFC2315])进行密码学增强的 MIME 主体部分。本规范还定义了 application/pkcs7-mime 媒体类型,可用于传输这些主体部分。
本文档还讨论了如何使用 [RFC1847] 中定义的 multipart/signed 媒体类型来传输 S/MIME 签名消息。multipart/signed 与 application/pkcs7-signature 媒体类型结合使用,后者用于传输分离的 S/MIME 签名。
为了创建 S/MIME 消息,S/MIME 代理必须遵循本文档中的规范,以及 [CMS]、[RFC3370]、[RFC4056]、[RFC3560] 和 [RFC5754] 中列出的规范。
在整个规范中,对接收代理如何处理传入消息提出了要求和给出建议。对发送代理如何创建传出消息也有分别的要求和建议。一般而言,最佳策略是遵循健壮性原理(对接收内容宽宏大量,对发送内容保守谨慎)。大多数要求针对传入消息的处理,而建议主要针对传出消息的创建。
对接收代理和发送代理的要求进行区分,也源于存在涉及传统 Internet 邮件客户端以外软件的 S/MIME 系统的可能性。S/MIME 可用于任何传输 MIME 数据的系统。例如,发送加密消息的自动化进程可能根本无法接收加密消息。因此,在适当时,对两类代理的要求和建议分别列出。
1.2. 定义
就本规范而言,适用以下定义。
ASN.1:抽象语法记法一(Abstract Syntax Notation One),如 ITU-T 建议 X.680、X.681、X.682 和 X.683 [ASN.1] 所定义。
BER:ASN.1 的基本编码规则(Basic Encoding Rules),如 ITU-T 建议 X.690 [X.690] 所定义。
Certificate(证书):一种通过数字签名将实体名称绑定到公钥的类型。
DER:ASN.1 的可分辨编码规则(Distinguished Encoding Rules),如 ITU-T 建议 X.690 [X.690] 所定义。
7-bit data(7 位数据):行长度小于 998 个字符、没有任何字符的第 8 位被置位、且没有 NULL 字符的文本数据。<CR> 和 <LF> 仅作为 <CR><LF> 行尾分隔符出现。
8-bit data(8 位数据):行长度小于 998 个字符、且没有任何字符为 NULL 字符的文本数据。<CR> 和 <LF> 仅作为 <CR><LF> 行尾分隔符出现。
Binary data(二进制数据):任意数据。
Transfer encoding(传输编码):对数据进行的一种可逆变换,以便 8 位或二进制数据能够通过仅传输 7 位数据的信道发送。
Receiving agent(接收代理):解释并处理 S/MIME CMS 对象、包含 CMS 内容类型的 MIME 主体部分,或两者的软件。
Sending agent(发送代理):创建 S/MIME CMS 内容类型、包含 CMS 内容类型的 MIME 主体部分,或两者的软件。
S/MIME agent(S/MIME 代理):作为接收代理、发送代理或两者的用户软件。
Data integrity service(数据完整性服务):一种通过确保对数据的变更可被发现来防止对数据未经授权更改的安全服务 [RFC4949]。
Data confidentiality(数据机密性):数据不被系统实体知悉,除非它们已被授权知悉该数据的属性 [RFC4949]。
1.3. 本文档使用的约定
关键词"MUST"、"MUST NOT"、"REQUIRED"、"SHALL"、"SHALL NOT"、"SHOULD"、"SHOULD NOT"、"RECOMMENDED"、"NOT RECOMMENDED"、"MAY"和"OPTIONAL"在本文档中,仅当它们以如这里所示的全大写形式出现时,才应按照 BCP 14 [RFC2119] [RFC8174] 中的描述进行解释。
我们定义了以下附加的要求级别:
SHOULD+:该术语含义同 SHOULD。但作者预期标有 SHOULD+ 的要求将在未来某个时间提升为 MUST。
SHOULD-:该术语含义同 SHOULD。但作者预期标有 SHOULD- 的要求将在本文档的未来版本降级为 MAY。
MUST-:该术语含义同 MUST。但作者预期该要求在未来文档中不再为 MUST。尽管其状态将在稍后确定,但合理预期,如果文档的未来修订改变了 MUST- 要求的状态,它将至少保持为 SHOULD 或 SHOULD-。
本文档中的术语"RSA"几乎总是指 PKCS #1 v1.5 RSA [RFC2313] 签名或加密算法,即使未如此限定。有少数地方它指通用的 RSA 密码学运算;这些可根据其使用上下文判断。
1.4. 与 S/MIME 既有实践的兼容性
S/MIME 版本 4.0 代理应当力求与先前版本的 S/MIME 代理实现最大程度的互操作。
- S/MIME 版本 2 在 RFC 2311 至 RFC 2315(含)[SMIMEv2] 中描述。
- S/MIME 版本 3 在 RFC 2630 至 RFC 2634(含)以及 RFC 5035 [SMIMEv3] 中描述。
- S/MIME 版本 3.1 在 RFC 2634、RFC 3850、RFC 3851、RFC 3852 和 RFC 5035 [SMIMEv3.1] 中描述。
- S/MIME 版本 3.2 在 RFC 2634、RFC 5035、RFC 5652、RFC 5750 和 RFC 5751 [SMIMEv3.2] 中描述。
- [RFC2311] 还包含关于 S/MIME 发展的历史信息。
1.5. 从 S/MIME v3 到 S/MIME v3.1 的变更
本节约描述了 S/MIME v3 与 S/MIME v3.1 之间的变更。注意,由大写关键词("MUST"、"SHOULD"等)所指示的要求级别可能在 S/MIME 的后续版本中发生变化。
- RSA 公钥算法被改为 MUST 实现。密钥包装算法和 Diffie-Hellman(DH)算法 [RFC2631] 被改为 SHOULD 实现。
- AES 对称加密算法被纳入为 SHOULD 实现。
- RSA 公钥算法被改为 MUST 实现的签名算法。
- 关于使用"空"SignedData 消息传输证书的含糊措辞被澄清,以反映同样允许传输证书撤销列表(CRL)。
- 对某些 MIME 实体使用二进制编码现已明确讨论。
- 通过 message/rfc822 媒体类型实现的头字段保护已被加入。
- 允许使用 CompressedData CMS 类型,以及所需的媒体类型和文件扩展名补充。
1.6. 从 S/MIME v3.1 到 S/MIME v3.2 的变更
本节约描述了 S/MIME v3.1 与 S/MIME v3.2 之间的变更。注意,由大写关键词("MUST"、"SHOULD"等)所指示的要求级别可能在 S/MIME 的后续版本中发生变化。注意此处列出的节号(例如 3.4.3.2)来自 [RFC5751]。
- 进行了编辑性修改,例如将"MIME type"替换为"media type","content-type"替换为"Content-Type"。
- 将"本文档使用的约定"移至第 1.3 节。增加了对 SHOULD+、SHOULD- 和 MUST- 的定义。
- 第 1.1 节和附录 A:增加了对 RSASSA-PSS、RSAES-OAEP 和 SHA2 CMS 算法的 RFC 引用。向 CMS 引用增加了 CMS 多签名者澄清。
- 第 1.2 节:将 ASN.1 引用更新为 X.680,BER 和 DER 更新为 X.690。
- 第 1.4 节:增加了对 S/MIME v3.1 RFC 的引用。
- 第 2.1 节(摘要算法):增加 SHA-256 为 MUST,SHA-1 和 MD5 改为 SHOULD-。
- 第 2.2 节(签名算法):增加 RSA with SHA-256 为 MUST;DSA with SHA-256 为 SHOULD+;RSA with SHA-1、DSA with SHA-1 和 RSA with MD5 改为 SHOULD-;RSASSA-PSS with SHA-256 增加为 SHOULD+。还增加了关于 S/MIME v3.1 客户端支持情况的说明。
- 第 2.3 节(密钥加密):DH 改为 SHOULD-,RSAES-OAEP 增加为 SHOULD+。详细说明了密钥包装算法的要求。
- 第 2.5.1 节:增加接收代理 MUST 同时支持 GeneralizedTime 和 UTCTime 的要求。
- 第 2.5.2 节:将引用"sha1WithRSAEncryption"替换为"sha256WithRSAEncryption",将"DES-3EDE-CBC"替换为"AES-128 CBC",并删除了 RC5 示例。
- 第 2.5.2.1 节:删除了整个小节(讨论已废弃的 RC2)。
- 第 2.7 节、第 2.7.1 节和附录 A:删除了对 RC2/40 的引用。
- 第 2.7 节(内容加密):增加 AES-128 CBC 为 MUST,AES-192 和 AES-256 CBC 为 SHOULD+,tripleDES 现在为 SHOULD-。
- 第 2.7.1 节:将指针从 2.7.2.1 至 2.7.2.4 更新为 2.7.1.1 和 2.7.1.2。
- 第 3.1.1 节:删除了关于 MIME 字符集的文本。
- 第 3.2.2 节和第 3.6 节:将"encrypted"替换为"enveloped"。将 OID 示例更新为使用 AES-128 CBC OID。
- 第 3.4.3.2 节:将"SHA-1"的"micalg"参数替换为"sha-1"。
- 第 4 节:更新了对 CERT v3.2 的引用。
- 第 4.1 节:更新了 RSA 和 DSA 密钥长度讨论。将最后四句移至安全考量。更新了对安全随机性要求的引用。
- 第 5 节:增加了 IANA 注册模板,将媒体类型注册表更新为指向本文档而非 RFC 2311。
- 第 6 节:更新了安全考量。
- 第 7 节:将引用从附录 B 移至此节。更新了引用。增加了对 SMIMEv2、SMIMEv3 和 SMIMEv3.1 的资料性引用。
- 附录 B:增加了附录 B 以将 S/MIME v2 移至历史状态。
1.7. S/MIME v4.0 的变更
本节约描述了 S/MIME v3.2 与 S/MIME v4.0 之间的变更。
- 增加了 AuthEnvelopedData 的使用,包括定义并注册一个 smime-type 值(第 2.4.4 节和第 3.4 节)。
- 更新了内容加密算法(第 2.7 节和第 2.7.1.2 节):增加 AES-256 伽罗瓦/计数器模式(GCM),增加 ChaCha20-Poly1305,删除对 AES-192 密码块链接(CBC)的提及,并将 tripleDES 标记为历史。
- 更新了一组签名算法(第 2.2 节):增加 Edwards 曲线数字签名算法(EdDSA),增加椭圆曲线数字签名算法(ECDSA),并将 DSA 标记为历史。
- 更新了一组摘要算法(第 2.1 节):增加 SHA-512,并将 SHA-1 标记为历史。
- 更新了用于 RSA 加密和 RSA 签名的密钥长度(第 4 节)。
- 创建了附录 B,讨论处理历史电子邮件消息的考量。
2. CMS 选项
CMS 在内容、属性和算法支持方面允许各种各样的选项。本节提出若干支持要求和推荐,以实现所有 S/MIME 实现之间的基本互操作水平。[RFC3370] 和 [RFC5754] 提供了关于密码算法使用的更多细节。[ESS] 提供了关于附加属性使用的更多细节。
2.1. DigestAlgorithmIdentifier
此处使用的算法用于对消息主体进行摘要,不同于作为签名算法一部分使用的摘要算法。其结果被放入签名属性的 message-digest 属性中。建议用于对消息主体进行摘要的算法强度应相似于或强于签名算法。
发送和接收代理:
- MUST 支持 SHA-256。
- MUST 支持 SHA-512。
[RFC5754] 提供了在 S/MIME 中使用这些算法的细节。
2.2. SignatureAlgorithmIdentifier
对接收代理和发送代理施加了不同的要求集。通过采用不同要求,可以实现最大程度的互操作,因为它允许对私钥材料进行专门保护,同时实现最大限度的签名验证。
接收代理:
- MUST 支持基于 P-256 曲线和 SHA-256 的 ECDSA。
- MUST 支持使用 PureEdDSA 模式的 curve25519 的 EdDSA [RFC8419]。
- MUST- 支持 RSA PKCS #1 v1.5 with SHA-256。
- SHOULD 支持 RSA 概率签名方案(RSASSA-PSS)with SHA-256。
发送代理:
- MUST 至少支持下列算法之一:基于 P-256 曲线和 SHA-256 的 ECDSA,或基于 PureEdDSA 模式的 curve25519 的 EdDSA。
- MUST- 支持 RSA PKCS #1 v1.5 with SHA-256。
- SHOULD 支持 RSASSA-PSS with SHA-256。
关于密钥长度和算法引用的信息见第 4.1 节。
2.3. KeyEncryptionAlgorithmIdentifier
接收和发送代理:
- MUST 支持如 [RFC5753] 规定的、针对 P-256 的椭圆曲线 Diffie-Hellman(ECDH)临时-静态模式。
- MUST 支持如 [RFC8418] 规定的、使用 HKDF-256("HKDF" 指"基于 HMAC 的密钥派生函数")作为 KDF 的、针对 X25519 的 ECDH 临时-静态模式。
- MUST- 支持如 [RFC3370] 规定的 RSA 加密。
- SHOULD+ 支持如 [RFC3560] 规定的 RSA 加密方案 - 最优非对称加密填充(RSAES-OAEP)。
当使用 ECDH 临时-静态时,KeyEncryptionAlgorithmIdentifier [RFC5652] 中还指定了密钥包装算法。密钥包装算法与内容加密算法 [RFC3370] [RFC3565] 的底层加密函数,以及这两种算法的密钥长度,必须相同(例如,AES-128 密钥包装算法配合 AES-128 内容加密算法)。由于 128 位和 256 位 AES 模式都作为内容加密算法是强制实现(MUST)的(第 2.7 节),当使用 ECDH 临时-静态时,AES-128 和 AES-256 密钥包装算法都必须被支持。收件人 MAY 强制执行此要求,但必须在它们可能所做的任何密码强度计算中使用两者中较弱的一个。
附录 B 提供了关于早期 S/MIME 版本中算法支持的信息。
2.4. 通用语法
有若干 CMS 内容类型。其中,目前仅 Data、SignedData、EnvelopedData、AuthEnvelopedData 和 CompressedData 内容类型用于 S/MIME。
2.4.1. Data 内容类型
发送代理 MUST 使用 id-data 内容类型标识符来标识"内部"MIME 消息内容。例如,当对 MIME 数据应用数字签名时,CMS SignedData 的 encapContentInfo eContentType MUST 包含 id-data 对象标识符(OID),且媒体类型 MUST 存储在 SignedData encapContentInfo eContent OCTET STRING 中(除非发送代理使用 multipart/signed,在这种情况下 eContent 缺失,见本文档第 3.5.3 节)。另一个例子,当对 MIME 数据应用加密时,CMS EnvelopedData 的 encryptedContentInfo contentType MUST 包含 id-data OID,且加密的 MIME 内容 MUST 存储在 EnvelopedData encryptedContentInfo encryptedContent OCTET STRING 中。
2.4.2. SignedData 内容类型
发送代理 MUST 使用 SignedData 内容类型对消息应用数字签名,或在退化情况下(没有签名信息)用于传输证书。对消息应用签名提供认证、消息完整性和起源不可否认性。
2.4.3. EnvelopedData 内容类型
此内容类型用于对消息应用数据机密性。为了分发对称密钥,发送者需要能够访问每个目标消息收件人的公钥才能使用此服务。
2.4.4. AuthEnvelopedData 内容类型
此内容类型用于对消息应用数据机密性和消息完整性。此内容类型不提供认证或不可否认性。为了分发对称密钥,发送者需要能够访问每个目标消息收件人的公钥才能使用此服务。
2.4.5. CompressedData 内容类型
此内容类型用于对消息应用数据压缩。此内容类型不提供认证、消息完整性、不可否认性或数据机密性;它仅用于减小消息的大小。
关于将此类型与其他 CMS 类型结合使用的进一步指导见第 3.7 节。
2.5. 属性与 SignerInfo 类型
SignerInfo 类型允许在签名的同时包含未签名和已签名属性。这些属性可能是处理消息所必需的(例如 message digest)、签名者提供的应被处理的信息(例如 SMIME capabilities),或与当前情况无关的属性(例如 mlExpansionHistory [RFC2634],供邮件查看器使用)。
接收代理 MUST 能够处理此处列出的每个已签名属性的零个或一个实例。发送代理 SHOULD 在每个 S/MIME 消息中生成以下每个已签名属性的一个实例:
- 签名时间(本文档第 2.5.1 节)
- SMIME 能力(本文档第 2.5.2 节)
- 加密密钥偏好(本文档第 2.5.3 节)
- 消息摘要([RFC5652] 第 11.2 节)
- 内容类型([RFC5652] 第 11.1 节)
此外,接收代理 SHOULD 能够处理 signingCertificate 和 signingCertificateV2 已签名属性的零个或一个实例,它们分别定义于 RFC 2634 [ESS] 的第 5 节和 RFC 5035 [ESS] 的第 3 节。
发送代理 SHOULD 在每个 SignerInfo 结构中生成 signingCertificate 或 signingCertificateV2 已签名属性的一个实例。
未来可能定义附加的属性以及这些属性的值。接收代理 SHOULD 以优雅的方式处理它们无法识别的属性或值。
包含此处未列出的已签名属性的交互式发送代理 SHOULD 向用户显示这些属性,以便用户知悉所有被签名的数据。
2.5.1. 签名时间属性
signingTime 属性用于传达消息被签名的时间。签名时间最可能由签名者创建,因此仅与其可信度相当。
发送代理 MUST 将 2049 年及之前的签名时间编码为 UTCTime;2050 年及之后的签名时间 MUST 编码为 GeneralizedTime。当使用 UTCTime 选项时,S/MIME 代理 MUST 如下解释年份字段(YY):
- 如果 YY 大于或等于 50,则年份解释为 19YY;
- 如果 YY 小于 50,则年份解释为 20YY。
接收代理 MUST 能够处理以 UTCTime 或 GeneralizedTime 编码的 signingTime 属性。
2.5.2. SMIMECapabilities 属性
SMIMECapabilities 属性包含签名算法(例如"sha256WithRSAEncryption")、对称算法(例如"AES-128 CBC")、认证对称算法(例如"AES-128 GCM")和密钥加密算法(例如"rsaEncryption")。包含某个算法的 SMIMECapability 属性的存在,意味着发送者能够处理该算法,并理解与该算法关联的 ASN.1 结构。还有若干标识对其他可选特性的支持的标识符,例如二进制编码和压缩。SMIMECapabilities 属性被设计得灵活且可扩展,以便未来能够以一种不会导致当前客户端崩溃的方式添加标识其他能力和偏好(例如证书)的方法。
如果存在,SMIMECapabilities 属性 MUST 是一个 SignedAttribute。CMS 将 SignedAttributes 定义为 Attribute 的 SET OF。signerInfo 中的 SignedAttributes MUST 包含 SMIMECapabilities 属性的单个实例。CMS 为 Attribute 定义的 ASN.1 语法包含 attrValues SET OF AttributeValue。SMIMECapabilities 属性 MUST 仅包含 AttributeValue 的单个实例。如果检测到违反这些要求的签名,该签名 SHOULD 被视为失败。
SMIMECapabilities 属性的语义规定了宣布该 SMIMECapabilities 的客户端所能支持的能力的部分列表。客户端不必列出它支持的每个能力,也无需列出其所有能力,以使能力列表不会变得过长。在 SMIMECapabilities 属性中,OID 按其偏好顺序列出,但 SHOULD 按类别(签名算法、对称算法、密钥加密算法等)在逻辑上分开。
SMIMECapabilities 属性的结构旨在便于简单的表查找和二进制比较,以确定匹配。例如,sha256WithRSAEncryption 的 SMIMECapability 编码包含而非省略 NULL 参数。由于要求编码完全相同,记录要在 SMIMECapabilities 属性中使用的算法的人 SHOULD 显式记录常见情况的正确的字节序列。
对于任何能力,OID 的关联参数 MUST 指定区分同一算法的两个实例所需的所有参数。
用于标识算法的同一 OID SHOULD 也用于该算法的 SMIMECapability 中。存在单个 OID 可对应多个算法的情况。在这些情况下,必须使用单个算法分配给使用该 OID 的 SMIMECapability。然后从 smimeCapabilities OID 树中为其他算法用法分配附加的 OID。例如,在早期规范中,rsaEncryption 是模糊的,因为它可能指签名算法或密钥加密算法。在某个 OID 含糊的情况下,需要由已注册的 SMIMECapabilities 列表的维护者来裁定哪类算法将使用该 OID,并且 MUST 在 smimeCapabilities OID 下分配一个新的 OID 以满足该 OID 的其他用途。
已注册的 SMIMECapabilities 列表为需要参数的 OID 指定参数,最显著的是可变长度对称密码的密钥长度。对于特定 OID 没有区分参数的情况,参数 MUST 省略,且 MUST NOT 编码为 NULL。SMIMECapabilities 属性的附加值可能在未来定义。接收代理 MUST 以优雅的方式处理具有它无法识别的值的 SMIMECapabilities 对象。
第 2.7.1 节解释了缓存能力的策略。
2.5.3. 加密密钥偏好属性
加密密钥偏好属性允许签名者明确描述签名者的哪个证书拥有其偏好的加密密钥。此属性旨在增强与那些对加密和签名使用分离密钥的客户端的互操作行为。此属性用于向查看该属性的任何人传达所列证书中哪一个适合为未来的加密消息加密会话密钥。
如果存在,SMIMEEncryptionKeyPreference 属性 MUST 是一个 SignedAttribute。CMS 将 SignedAttributes 定义为 Attribute 的 SET OF。signerInfo 中的 SignedAttributes MUST 包含 SMIMEEncryptionKeyPreference 属性的单个实例。CMS 为 Attribute 定义的 ASN.1 语法包含 attrValues SET OF AttributeValue。SMIMEEncryptionKeyPreference 属性 MUST 仅包含 AttributeValue 的单个实例。如果检测到违反这些要求的签名,该签名 SHOULD 被视为失败。
如果使用此属性,发送代理 SHOULD 将所引用的证书包含在签名消息所包含的证书集合中。如果该证书先前已提供给接收代理,则可以省略。如果常用的或偏好的加密证书与用于签署消息的证书不同,发送代理 SHOULD 使用此属性。
接收代理 SHOULD 在消息上的签名有效且签名时间大于当前存储值时存储该偏好数据。(与 SMIMECapabilities 一样,SHOULD 检查时钟偏移,如果偏移过大则不使用该数据。)接收代理 SHOULD 尽可能尊重发送者的加密密钥偏好属性。然而,这仅代表一种偏好,接收代理可以使用回复发送者时任何有效的证书。
第 2.7.1 节解释了缓存偏好数据的策略。
2.5.3.1. 收件人密钥管理证书的选择
为了确定在为特定收件人发送未来 CMS EnvelopedData 消息时要使用的密钥管理证书,SHOULD 遵循以下步骤:
- 如果在来自期望收件人的 SignedData 对象中找到 SMIMEEncryptionKeyPreference 属性,则该属性标识了应作为该收件人的 X.509 密钥管理证书的 X.509 证书。
- 如果在来自期望收件人的 SignedData 对象中未找到 SMIMEEncryptionKeyPreference 属性,则 SHOULD 在 X.509 证书集合中搜索具有相同主体名称、且可作为密钥管理之用的 X.509 证书签名者的 X.509 证书。
- 或者,使用某种其他方法确定用户的密钥管理密钥。如果未找到 X.509 密钥管理证书,则无法使用消息签名者进行加密。如果找到多个 X.509 密钥管理证书,S/MIME 代理可以在它们之间进行任意选择。
2.6. SignerIdentifier SignerInfo 类型
S/MIME v4.0 实现 MUST 同时支持 issuerAndSerialNumber 和 subjectKeyIdentifier。使用 subjectKeyIdentifier 选项的消息无法被 S/MIME v2 客户端读取。
重要的是要理解,某些证书使用的 subjectKeyIdentifier 值不适合唯一标识一个证书。实现 MUST 准备好应对可能为不同实体的多个证书具有相同的 subjectKeyIdentifier 值的情况,并且 MUST 准备好在指示错误条件之前,在签名验证期间尝试每个匹配的证书。
2.7. ContentEncryptionAlgorithmIdentifier
发送和接收代理:
- MUST 支持使用 AES-128 GCM 和 AES-256 GCM [RFC5084] 进行加密和解密。
- MUST- 支持使用 AES-128 CBC [RFC3565] 进行加密和解密。
- SHOULD+ 支持使用 ChaCha20-Poly1305 [RFC7905] 进行加密和解密。
2.7.1. 决定使用哪种加密方法
当发送代理创建加密消息时,它必须决定使用哪种加密类型。决策过程涉及使用从收件人传入消息中包含的能力列表获得的信息,以及带外信息,例如私下约定、用户偏好、法律限制等。
第 2.5.2 节定义了一种方法,发送代理可借此可选地宣布其解密能力及其偏好顺序。SHOULD 使用以下方法来处理和记忆传入签名消息中的加密能力属性。
- 如果接收代理尚未为发送者的公钥创建能力列表,则在验证传入消息上的签名并检查时间戳后,接收代理 SHOULD 创建一个至少包含签名时间和对称能力的新列表。
- 如果这样的列表已存在,接收代理 SHOULD 验证传入消息中的签名时间大于列表中存储的签名时间,且签名有效。如果是,接收代理 SHOULD 更新列表中的签名时间和能力。远在未来的签名时间值(即偏差大于任何合理的时钟偏移),或签名无法验证的消息中的能力列表,MUST NOT 被接受。
能力列表 SHOULD 存储以备将来创建消息时使用。
在发送消息之前,发送代理 MUST 决定它是否愿意对该消息中的特定数据使用弱加密。如果发送代理决定弱加密对该数据不可接受,则发送代理 MUST NOT 使用弱算法。使用或不使用弱加密的决定凌驾于本节中关于使用哪种加密算法的任何其他决定。
第 2.7.1.1 节和 2.7.1.2 节描述了发送代理在选择将应用于消息的加密类型时 SHOULD 使用的决策。这些规则是有序的,因此发送代理 SHOULD 按给定顺序做出决定。
2.7.1.1. 规则 1:已知能力
如果发送代理已收到它即将加密的消息的收件人的一组能力,则发送代理 SHOULD 通过选择列表中的第一个能力(即目标收件人最偏好的能力)来使用这些信息,前提是该发送代理知道如何加密。如果发送代理合理预期收件人能够解密该消息,则发送代理 SHOULD 使用列表中的能力之一。
2.7.1.2. 规则 2:未知能力、未知 S/MIME 版本
如果满足以下两个条件,发送代理 SHOULD 使用 AES-256 GCM,因为 AES-256 GCM 是更强的算法,且由 S/MIME v4.0 要求:
- 发送代理不知道收件人的加密能力。
- 发送代理不知道收件人使用或支持的 S/MIME 版本。
如果发送代理在此步骤选择不使用 AES-256 GCM,鉴于假设实现 AES-GCM 的客户端会同时实现 AES-256 和 AES-128,它 SHOULD 使用 AES-128 CBC。
2.7.2. 选择弱加密
诸如 RC2 之类的算法被认为是弱加密算法。诸如 TripleDES 之类的算法并非当前最先进技术,且被认为比 AES 弱。由人类控制的发送代理 SHOULD 允许人类发送者在发送数据之前确定使用较弱加密算法发送数据的风险,并可能允许人类使用更强的加密算法(例如 AES GCM 或 AES CBC),即使存在收件人可能无法处理该算法的可能性。
2.7.3. 多个收件人
如果发送代理正在编写一条加密消息给一组收件人,其中某些收件人的加密能力不重叠,发送代理被迫发送多于一条消息。请注意,如果发送代理选择发送用强算法加密的消息,然后发送用弱算法加密的相同消息,监视通信信道的人可能仅仅通过解密弱加密消息就能获知强加密消息的内容。
3. 创建 S/MIME 消息
本节描述 S/MIME 消息格式及其创建方式。S/MIME 消息是 MIME 主体与 CMS 内容类型的组合。使用了若干媒体类型和若干 CMS 内容类型。要保护的数据始终是规范化的 MIME 实体。MIME 实体和其他数据(例如证书和算法标识符)被交给 CMS 处理设施,后者产生一个 CMS 对象。最后,CMS 对象被包裹在 MIME 中。"S/MIME 的增强安全服务"文档 [ESS] 提供了嵌套的、安全的 S/MIME 消息如何格式化的描述。ESS 描述了如何使用 multipart/signed 和 application/pkcs7-mime 为签名格式化三重包装(triple-wrapped)的 S/MIME 消息。
S/MIME 为纯封装数据提供一种格式,为纯签名数据提供若干格式,为签名并封装的数据提供若干格式。需要若干格式以适应若干环境——特别是对于签名消息。也描述了在这些格式之间进行选择的准则。
阅读本节的人应理解 [MIME-SPEC] 和 [RFC1847] 中描述的 MIME。
3.1. 为签名、封装或压缩准备 MIME 实体
S/MIME 用于保护 MIME 实体。MIME 消息由 MIME 头和 MIME 主体组成。主体可以由单个 MIME 实体或一棵 MIME 实体树(以 multipart 为根)组成。S/MIME 可用于保护单个 MIME 实体或一棵 MIME 实体树。这些实体可以位于根以外的位置。S/MIME 可以多次应用于单个消息中的不同实体。作为整条消息的 MIME 实体仅包含 MIME 消息头和 MIME 主体,不包含 rfc822 头。注意,S/MIME 也可用于保护 Internet 邮件以外应用中使用的 MIME 实体。对于需要保护 rfc822 头的情况,本节后面解释了使用 message/rfc822 媒体类型。
本节描述并保护的 MIME 实体可被视为"内部"MIME 实体。即,它可能是更大 MIME 消息中的"最内层"对象。将"外部"MIME 实体处理为 CMS EnvelopedData、CompressedData 和 AuthEnvelopedData 内容类型在第 3.2 节和第 3.5 节描述。其他文档定义了附加的 CMS 内容类型;处理那些 CMS 内容类型应参考那些文档。
准备 MIME 实体的过程在 [MIME-SPEC] 中给出。这里使用相同的过程,但在签名时有一些附加限制。[MIME-SPEC] 中过程的描述在此重复,但建议读者参考那些文档以获取确切过程。本节还描述了附加要求。
用于创建将进行任意组合的签名、封装和压缩的 MIME 实体的过程是单一的。建议执行一些附加步骤,以防御在邮件传输期间可能发生的、对使用 multipart/signed 格式进行明文签名尤其重要的已知损坏。建议对这些附加步骤也应用于封装消息,或签名并封装的消息,以便消息无需修改即可转发到任何环境。
这些步骤是描述性的而非规定性的。实现者可以自由使用任何过程,只要结果相同。
步骤 1. 根据本地约定准备 MIME 实体。
步骤 2. 将 MIME 实体的叶部分转换为规范化形式。
步骤 3. 对 MIME 实体的叶部分应用适当的传输编码。
当收到 S/MIME 消息时,处理消息上的安全服务,结果是 MIME 实体。该 MIME 实体通常被传递给支持 MIME 的用户代理,在那里被进一步解码并呈现给用户或接收应用。
为了保护外部的、非内容相关的消息头字段(例如"Subject"、"To"、"From"和"Cc"字段),发送客户端 MAY 将完整的 MIME 消息包裹在 message/rfc822 包装器中,以便对这些头字段应用 S/MIME 安全服务。由接收客户端决定如何呈现这个"内部"头以及未受保护的"外部"头。鉴于头之间的安全差异,建议接收客户端根据头字段的位置提供区分。
当收到 S/MIME 消息时,如果受保护的最顶层 MIME 实体的 Content-Type 为 message/rfc822,则可假定其意图是提供头保护。该实体 SHOULD 作为最顶层消息呈现,并考虑前述的头合并问题。
3.1.1. 规范化
每个 MIME 实体 MUST 转换为在创建签名的环境和验证签名的环境都能唯一且无歧义表示的规范化形式。MIME 实体 MUST 为封装和压缩以及签名的规范化。
规范化的确切细节取决于实体的实际媒体类型和子类型,此处不描述。相反,应参考特定媒体类型的标准。例如,text/plain 的规范化不同于 audio/basic 的规范化。除文本类型外,大多数类型只有一种表示,无论计算平台或环境如何,都可被视为其规范化表示。
一般而言,规范化将由发送代理的非安全部分而非 S/MIME 实现来执行。
最常见且最重要的规范化是针对文本的,文本在不同环境中的表示通常不同。主类型为"text"的 MIME 实体 MUST 同时对其行尾和字符集进行规范化。行尾 MUST 是字符对 <CR><LF>,且字符集 SHOULD 是已注册的字符集 [CHARSETS]。规范化的细节在 [MIME-SPEC] 中指定。
注意,某些字符集(如 ISO-2022)对同一字符有多种表示。在为签名准备此类文本时,MUST 使用为该字符集指定的规范化表示。
3.1.2. 传输编码
当生成以下任何受保护的 MIME 实体时(使用 multipart/signed 格式签名的情况除外),完全不需要传输编码。S/MIME 实现 MUST 能够处理二进制 MIME 对象。如果不存在 Content-Transfer-Encoding 头字段,则假定传输编码为 7BIT。
作为规则,S/MIME 实现 SHOULD 对其保护的所有 MIME 实体使用第 3.1.3 节描述的传输编码。即使对于未暴露于传输的封装数据,也仅保护 7 位 MIME 实体的原因在于,它允许 MIME 实体在任何环境中无需更改即可处理。例如,可信网关可能移除消息的信封但保留签名,然后将签名消息转发给最终收件人,以便他们可以直接验证签名。如果站点内部的传输不是 8 位干净的(例如在具有单一邮件网关的广域网上),除非原始 MIME 实体仅为 7 位数据,否则验证签名将无法进行。
在 S/MIME 实现能够确定所有目标收件人都能够处理内部(除最外层外的所有)二进制 MIME 对象的情况下,实现 SHOULD 对内部实体使用二进制编码,而不是 7 位安全的传输编码。使用 7 位安全的编码(例如 base64)会不必要地扩大消息大小。实现 MAY 通过(1)解释 id-cap-preferBinaryInside SMIMECapabilities 属性,(2)事先约定,或(3)其他方式,来确定收件人实现能够处理内部二进制 MIME 实体。
如果一个或多个目标收件人无法处理内部二进制 MIME 对象,或者对于任何目标收件人此能力未知,S/MIME 实现 SHOULD 对其保护的所有 MIME 实体使用第 3.1.3 节描述的传输编码。
3.1.3. 使用 multipart/signed 签名的传输编码
如果 multipart/signed 实体曾经要通过标准 Internet SMTP 基础设施或其他限制为 7 位文本的传输发送,它 MUST 应用传输编码,以便表示为 7 位文本。已经是 7 位数据的 MIME 实体不需要传输编码。诸如 8 位文本和二进制数据之类的实体可以用 quoted-printable 或 base64 传输编码进行编码。
7 位要求的主要原因是 Internet 邮件传输基础设施无法保证传输 8 位或二进制数据。尽管传输基础设施的许多部分现在处理 8 位甚至二进制数据,但有时无法知道传输路径是否是 8 位干净的。如果带有 8 位数据的邮件消息遇到无法传输 8 位或二进制数据的消息传输代理,该代理有三种选择,没有一种对明文签名消息是可接受的:
- 代理可能更改传输编码;这将使签名失效。
- 代理可能无论如何传输数据,这极有可能导致第 8 位被破坏;这也会使签名失效。
- 代理可能将消息返回给发送者。
[RFC1847] 禁止代理更改 multipart/signed 消息第一部分的传输编码。如果无法传输 8 位或二进制数据的合规代理遇到第一部分包含 8 位或二进制数据的 multipart/signed 消息,它将不得不将该消息作为不可投递返回给发送者。
3.1.4. 规范化 MIME 实体示例
此示例展示了一个带有完整传输编码的 multipart/mixed 消息。此消息包含文本部分和附件。示例消息文本包含非 ASCII 字符,因此需要传输编码。尽管此处未显示,每行行尾是 <CR><LF>。MIME 头、文本和传输编码部分的行尾 MUST 都是 <CR><LF>。
注意,此示例并非 S/MIME 消息的示例。
Content-Type: multipart/mixed; boundary=bar --bar Content-Type: text/plain; charset=iso-8859-1 Content-Transfer-Encoding: quoted-printable =A1Hola Michael! How do you like the new S/MIME specification? It's generally a good idea to encode lines that begin with From=20because some mail transport agents will insert a greater-than (>) sign, thus invalidating the signature. Also, in some cases it might be desirable to encode any =20 trailing whitespace that occurs on lines in order to ensure =20 that the message signature is not invalidated when passing =20 a gateway that modifies such whitespace (like BITNET). =20 --bar Content-Type: image/jpeg Content-Transfer-Encoding: base64 iQCVAwUBMJrRF2N9oWBghPDJAQE9UQQAtl7LuRVndBjrk4EqYBIb3h5QXIX/LC// jJV5bNvkZIGPIcEmI5iFd9boEgvpirHtIREEqLQRkYNoBActFBZmh9GC3C041WGq uMbrbxc+nIs1TIKlA08rVi9ig/2Yh7LFrK5Ein57U/W72vgSxLhe/zhdfolT9Brn HOxEa44b+EI= --bar--
3.2. application/pkcs7-mime 媒体类型
application/pkcs7-mime 媒体类型用于承载 CMS 内容类型,包括 EnvelopedData、SignedData 和 CompressedData。构建这些实体的细节在后续章节描述。本节描述 application/pkcs7-mime 媒体类型的一般特性。
如果 eContentType 是 id-data,所承载的 CMS 对象始终包含按照第 3.1 节准备的 MIME 实体。当 eContentType 包含不同值时,可以承载其他内容。有关签名回执的示例,请参见 [ESS]。
由于 CMS 内容类型是二进制数据,在大多数情况下 base64 传输编码是合适的——特别是当与 SMTP 传输一起使用时。所使用的传输编码取决于对象要发送的传输通道,而不是媒体类型的特性。
注意,此讨论指的是 CMS 对象或"外部"MIME 实体的传输编码。它与由 CMS 对象保护的 MIME 实体(即第 3.1 节描述的"内部"对象)的传输编码完全独立且不相关。
由于有若干类型的 application/pkcs7-mime 对象,发送代理 SHOULD 尽可能帮助接收代理在不强制其解码对象的 ASN.1 的情况下了解对象的内容。所有 application/pkcs7-mime 对象的 Content-Type 头字段 SHOULD 包含可选的"smime-type"参数,如下节所述。
3.2.1. name 与 filename 参数
对于 application/pkcs7-mime,发送代理 SHOULD 发出 Content-Type 字段的可选"name"参数,以与较旧的系统兼容。发送代理 SHOULD 还发出可选的 Content-Disposition 字段 [RFC2183] 及其"filename"参数。如果发送代理发出上述参数,参数的值 SHOULD 是带有适当扩展名的文件名:
| 媒体类型 | 文件扩展名 |
|---|---|
| application/pkcs7-mime(SignedData、EnvelopedData、AuthEnvelopedData) | .p7m |
| application/pkcs7-mime(退化 SignedData 证书管理消息) | .p7c |
| application/pkcs7-mime(CompressedData) | .p7z |
| application/pkcs7-signature(SignedData) | .p7s |
此外,文件名 SHOULD 限制为八个字符加三个字母的扩展名。八字符文件名基可以是任意不同的名称;应使用文件名基"smime"来指示该 MIME 实体与 S/MIME 关联。
包含文件名有两个目的。它便于将 S/MIME 对象作为磁盘上的文件使用。它还能跨网关传达类型信息。当(例如)类型为 application/pkcs7-mime 的 MIME 实体到达对 S/MIME 没有特殊知识的网关时,它会将该实体的媒体类型默认为 application/octet-stream 并作为通用附件处理,从而丢失类型信息。然而,建议的附件文件名通常被跨网关携带。这通常允许接收系统确定将附件交给哪个适当的应用——在本例中,是一个独立的 S/MIME 处理应用。注意,提供此机制是作为某些环境中实现的便利。正确的 S/MIME 实现 MUST 使用媒体类型,且 MUST NOT 依赖文件扩展名。
3.2.2. smime-type 参数
application/pkcs7-mime 内容类型定义了可选的"smime-type"参数。该参数的意图是传达关于所应用安全(签名或封装)的细节,以及关于所包含内容的信息。本规范定义了以下 smime-type。
| 名称 | CMS 类型 | 内部内容 |
|---|---|---|
| enveloped-data | EnvelopedData | id-data |
| signed-data | SignedData | id-data |
| certs-only | SignedData | id-data |
| compressed-data | CompressedData | id-data |
| authEnveloped-data | AuthEnvelopedData | id-data |
为了与未来规范保持一致,分配新的 smime-type 参数时应遵循以下准则。
- 如果签名和加密都可以应用于内容,则 SHOULD 分配三个 smime-type 值:"signed-*"、"authEnv-*" 和 "enveloped-*"。如果可以分配一个操作,则可省略。因此,由于"certs-only"只能被签名,"signed-"被省略。
- SHOULD 为内容 OID 分配一个通用字符串。当 MIME 是内部内容时,我们对 id-data 内容 OID 使用"data"。
- 如果未分配通用字符串,则推荐使用"OID.<oid>"形式的通用字符串(例如,"OID.2.16.840.1.101.3.4.1.2"将是 AES-128 CBC)。
明确意图是此字段作为邮件客户端应用的合适提示,以指示消息是"已签名"、"authEnveloped"还是"已封装",而无需隧穿进入 CMS 载荷。
附加 smime-type 参数值的注册表已在 [RFC7114] 中定义。
3.3. 创建纯封装消息
本节描述在不签名的情况下封装 MIME 实体的格式。重要的是要注意,发送已封装但未签名的消息不提供数据完整性。"纯封装"结构不支持认证的对称算法。对这些算法使用"认证封装"结构。因此,可能以这样的方式替换密文:处理后的消息仍然有效,但含义可能被改变。
步骤 1. 根据第 3.1 节准备要封装的 MIME 实体。
步骤 2. 将 MIME 实体和其他所需数据处理为 EnvelopedData 类型的 CMS 对象。除了为每个收件人加密一份内容加密密钥(CEK)的副本外,SHOULD 为发起者加密一份 CEK 副本并包含在 EnvelopedData 中(见 [RFC5652] 第 6 节)。
步骤 3. 将 EnvelopedData 对象包裹在 CMS ContentInfo 对象中。
步骤 4. 将 ContentInfo 对象插入 application/pkcs7-mime MIME 实体。
纯封装消息的 smime-type 参数为"enveloped-data"。此类消息的文件扩展名为".p7m"。
示例消息如下:
Content-Type: application/pkcs7-mime; name=smime.p7m; smime-type=enveloped-data Content-Transfer-Encoding: base64 Content-Disposition: attachment; filename=smime.p7m MIIBHgYJKoZIhvcNAQcDoIIBDzCCAQsCAQAxgcAwgb0CAQAwJjASMRAwDgYDVQQDEw dDYXJsUlNBAhBGNGvHgABWvBHTbi7NXXHQMA0GCSqGSIb3DQEBAQUABIGAC3EN5nGI iJi2lsGPcP2iJ97a4e8kbKQz36zg6Z2i0yx6zYC4mZ7mX7FBs3IWg+f6KgCLx3M1eC bWx8+MDFbbpXadCDgO8/nUkUNYeNxJtuzubGgzoyEd8Ch4H/dd9gdzTd+taTEgS0ip dSJuNnkVY4/M652jKKHRLFf02hosdR8wQwYJKoZIhvcNAQcBMBQGCCqGSIb3DQMHBA gtaMXpRwZRNYAgDsiSf8Z9P43LrY4OxUk660cu1lXeCSFOSOpOJ7FuVyU=
3.4. 创建纯认证封装消息
本节描述在不签名的情况下封装 MIME 实体的格式。认证封装消息提供机密性和数据完整性。重要的是要注意,使用 S/MIME 发送认证封装消息不提供起源证明。第三方可能以这样的方式替换密文:处理后的消息仍然有效,但含义可能被改变。然而,这比纯封装消息要困难得多,因为该算法确实提供了一定程度的认证。任何为其加密该消息的收件人都可以在不被察觉的情况下替换它。
步骤 1. 根据第 3.1 节准备要封装的 MIME 实体。
步骤 2. 将 MIME 实体和其他所需数据处理为 AuthEnvelopedData 类型的 CMS 对象。除了为每个收件人加密一份 CEK 的副本外,SHOULD 为发起者加密一份 CEK 副本并包含在 AuthEnvelopedData 中(见 [RFC5083])。
步骤 3. 将 AuthEnvelopedData 对象包裹在 CMS ContentInfo 对象中。
步骤 4. 将 ContentInfo 对象插入 application/pkcs7-mime MIME 实体。
纯认证封装消息的 smime-type 参数为"authEnveloped-data"。此类消息的文件扩展名为".p7m"。
示例消息如下:
Content-Type: application/pkcs7-mime; smime-type=authEnveloped-data; name=smime.p7m Content-Transfer-Encoding: base64 Content-Disposition: attachment; filename=smime.p7m MIIDWQYLKoZIhvcNAQkQARegggNIMIIDRAIBADGBvjCBuwIBADAmMBIxEDAO BgNVBAMTB0NhcmxSU0ECEEY0a8eAAFa8EdNuLs1dcdAwCwYJKoZIhvcNAQEB BIGAgyZJo0ERTxA4xdTri5P5tVMyh0RARepTUCORZvlUbcUlaI8IpJZH3/J1 Fv6MxTRS4O/K+ZcTlQmYeWLQvwdltQdOIP3mhpqXzTnOYhTK1IDtF2zx75Lg vE+ilpcLIzXfJB4RCBPtBWaHAof4Wb+VMQvLkk9OolX4mRSH1LPktgAwggJq BgkqhkiG9w0BBwEwGwYJYIZIAWUDBAEGMA4EDGPizioC9OHSsnNx4oCCAj7Y Cb8rOy8+55106newEJohC/aDgWbJhrMKzSOwa7JraXOV3HXD3NvKbl665dRx vmDwSCNaLCRU5q8/AxQx2SvnAbM+JKcEfC/VFdd4SiHNiUECAApLku2rMi5B WrhW/FXmx9d+cjum2BRwB3wj0q1wajdB0/kVRbQwg697dnlYyUog4vpJERjr 7KAkawZx1RMHaM18wgZjUNpCBXFS3chQi9mTBp2i2Hf5iZ8OOtTx+rCQUmI6 Jhy03vdcPCCARBjn3v0d3upZYDZddMA41CB9fKnnWFjadV1KpYwv80tqsEfx Vo0lJQ5VtJ8MHJiBpLVKadRIZ4iH2ULC0JtN5mXE1SrFKh7cqbJ4+7nqSRL3 oBTud3rX41DGshOjpqcYHT4sqYlgZkc6dp0g1+hF1p3cGmjHdpysV2NVSUev ghHbvSqhIsXFzRSWKiZOigmlkv3R5LnjpYyP4brM62Jl7y0qborvV4dNMz7m D+5YxSlH0KAe8z6TT3LHuQdN7QCkFoiUSCaNhpAFaakkGIpqcqLhpOK4lXxt kptCG93eUwNCcTxtx6bXufPR5TUHohvZvfeqMp42kL37FJC/A8ZHoOxXy8+X X5QYxCQNuofWlvnIWv0Nr8w65x6lgVjPYmd/cHwzQKBTBMXN6pBud/PZL5zF tw3QHlQkBR+UflMWZKeN9L0KdQ27mQlCo5gQS85aifxoiiA2v9+0hxZw91rP IW4D+GS7oMMoKj8ZNyCJJsyf5smRZ+WxeBoolb3+TiGcBBCsRnfe6noLZiFO 6Zeu2ZwE
3.5. 创建纯签名消息
S/MIME 定义了两种格式的签名消息:
- 使用 SignedData 的 application/pkcs7-mime。
- multipart/signed。
一般而言,发送时偏好 multipart/signed 形式,且接收代理 MUST 能够处理两者。
3.5.1. 为纯签名消息选择格式
关于选择特定纯签名格式的时机没有硬性规定。它取决于所有接收者的能力,以及具有 S/MIME 设施的接收者能够验证签名与没有 S/MIME 软件的用户能够查看消息的相对重要性。
使用 multipart/signed 格式签名的消息总是可以被接收者查看,无论他们是否有 S/MIME 软件。无论他们使用的是原生 MIME 用户代理,还是消息由网关翻译,都可以查看。在此上下文中,"可查看"意味着基本上能够像处理非签名消息一样处理该消息,包括消息可能具有的任何其他 MIME 结构。
使用 SignedData 格式签名的消息,除非收件人有 S/MIME 设施,否则无法查看。然而,SignedData 格式保护消息内容不被良性中间代理更改。此类代理可能进行换行或内容传输编码更改,从而破坏签名。
3.5.2. 使用 application/pkcs7-mime 与 SignedData 签名
此签名格式使用 application/pkcs7-mime 媒体类型。创建此格式的步骤如下:
步骤 1. 根据第 3.1 节准备 MIME 实体。
步骤 2. 将 MIME 实体和其他所需数据处理为 SignedData 类型的 CMS 对象。
步骤 3. 将 SignedData 对象包裹在 CMS ContentInfo 对象中。
步骤 4. 将 ContentInfo 对象插入 application/pkcs7-mime MIME 实体。
使用 application/pkcs7-mime 与 SignedData 的消息的 smime-type 参数为"signed-data"。此类消息的文件扩展名为".p7m"。
示例消息如下:
Content-Type: application/pkcs7-mime; smime-type=signed-data; name=smime.p7m Content-Transfer-Encoding: base64 Content-Disposition: attachment; filename=smime.p7m MIIDmQYJKoZIhvcNAQcCoIIDijCCA4YCAQExCTAHBgUrDgMCGjAtBgkqhkiG9w0BBw GgIAQeDQpUaGlzIGlzIHNvbWUgc2FtcGxlIGNvbnRlbnQuoIIC4DCCAtwwggKboAMC AQICAgDIMAkGByqGSM44BAMwEjEQMA4GA1UEAxMHQ2FybERTUzAeFw05OTA4MTcwMT EwNDlaFw0zOTEyMzEyMzU5NTlaMBMxETAPBgNVBAMTCEFsaWNlRFNTMIIBtjCCASsG ByqGSM44BAEwggEeAoGBAIGNze2D6gqeOT7CSCij5EeT3Q7XqA7sU8WrhAhP/5Thc0 h+DNbzREjR/p+vpKGJL+HZMMg23j+bv7dM3F9piuR10DcMkQiVm96nXvn89J8v3UOo i1TxP7AHCEdNXYjDw7Wz41UIddU5dhDEeL3/nbCElzfy5FEbteQJllzzflvbAhUA4k emGkVmuBPG2o+4NyErYov3k80CgYAmONAUiTKqOfs+bdlLWWpMdiM5BAI1XPLLGjDD HlBd3ZtZ4s2qBT1YwHuiNrhuB699ikIlp/R1z0oIXks+kPht6pzJIYo7dhTpzi5dow fNI4W4LzABfG1JiRGJNkS9+MiVSlNWteL5c+waYTYfEX/Cve3RUP+YdMLRgUpgObo2 OQOBhAACgYBc47ladRSWC6l63eM/qeysXty9txMRNKYWiSgRI9k0hmd1dRMSPUNbb+ VRv/qJ8qIbPiR9PQeNW2PIu0WloErjhdbOBoA/6CN+GvIkq1MauCcNHu8Iv2YUgFxi rGX6FYvxuzTU0pY39mFHssQyhPB+QUD9RqdjTjPypeL08oPluKOBgTB/MAwGA1UdEw EB/wQCMAAwDgYDVR0PAQH/BAQDAgbAMB8GA1UdIwQYMBaAFHBEPoIub4feStN14z0g vEMrk/EfMB0GA1UdDgQWBBS+bKGz48H37UNwpM4TAeL945f+zTAfBgNVHREEGDAWgR RBbGljZURTU0BleGFtcGxlLmNvbTAJBgcqhkjOOAQDAzAAMC0CFFUMpBkfQiuJcSIz jYNqtT1na79FAhUAn2FTUlQLXLLd2ud2HeIQUltDXr0xYzBhAgEBMBgwEjEQMA4GA1 UEAxMHQ2FybERTUwICAMgwBwYFKw4DAhowCQYHKoZIzjgEAwQuMCwCFD1cSW6LIUFz eXle3YI5SKSBer/sAhQmCq7s/CTFHOEjgASeUjbMpx5g6A==
3.5.3. 使用 multipart/signed 格式签名
此格式是明文签名格式。没有任何 S/MIME 或 CMS 处理设施的收件人能够查看消息。它利用 [RFC1847] 中描述的 multipart/signed 媒体类型。multipart/signed 媒体类型有两部分。第一部分包含被签名的 MIME 实体;第二部分包含"分离签名"CMS SignedData 对象,其中 encapContentInfo eContent 字段缺失。
3.5.3.1. application/pkcs7-signature 媒体类型
此媒体类型始终包含单个 CMS 对象类型为 SignedData 的 CMS ContentInfo。SignedData encapContentInfo eContent 字段 MUST 缺失。signerInfos 字段包含 MIME 实体的签名。
使用 application/pkcs7-signature 的纯签名消息的文件扩展名为".p7s"。
3.5.3.2. 创建 multipart/signed 消息
步骤 1. 根据第 3.1 节准备要签名的 MIME 实体,对明文签名特别小心。
步骤 2. 将 MIME 实体交给 CMS 处理,以获得 encapContentInfo eContent 字段缺失的 SignedData 类型对象。
步骤 3. 将 MIME 实体插入 multipart/signed 消息的第一部分,除第 3.1 节描述的处理外不做其他处理。
步骤 4. 对"分离签名"CMS SignedData 对象应用传输编码,并将其插入 application/pkcs7-signature 类型的 MIME 实体。
步骤 5. 将 application/pkcs7-signature 的 MIME 实体插入 multipart/signed 实体的第二部分。
multipart/signed 的 Content-Type 有两个必需参数:protocol 参数和 micalg 参数。
protocol 参数 MUST 为"application/pkcs7-signature"。注意引号是必需的,因为 MIME 要求参数值中的"/"字符 MUST 被引用。
micalg 参数允许在验证签名时进行一遍处理。micalg 参数的值取决于计算消息完整性检查(MIC)时使用的消息摘要算法。如果使用了多个消息摘要算法,它们 MUST 按 [RFC1847] 用逗号分隔。应放入 micalg 参数的值 SHOULD 来自以下:
| 算法 | 使用的值 |
|---|---|
| MD5* | md5 |
| SHA-1* | sha-1 |
| SHA-224 | sha-224 |
| SHA-256 | sha-256 |
| SHA-384 | sha-384 |
| SHA-512 | sha-512 |
| 任何其他 | (在算法概要中单独定义,若未定义则为"unknown") |
*注:MD5 和 SHA-1 是历史性的,不再被视为安全。详见附录 B。
(历史注记:一些早期的 S/MIME 实现为 micalg 参数发出并期望"rsa-md5"、"rsa-sha1"和"sha1"。)接收代理 SHOULD 能够从容地从它无法识别的 micalg 参数值中恢复。此参数的未来值将取自 IANA"Hash Function Textual Names"注册表。
3.5.3.3. multipart/signed 消息示例
Content-Type: multipart/signed;
micalg=sha-256;
boundary="----=_NextBoundary____Fri,_06_Sep_2002_00:25:21";
protocol="application/pkcs7-signature"
This is a multipart message in MIME format.
------=_NextBoundary____Fri,_06_Sep_2002_00:25:21
This is some sample content.
------=_NextBoundary____Fri,_06_Sep_2002_00:25:21
Content-Type: application/pkcs7-signature; name=smime.p7s
Content-Transfer-Encoding: base64
Content-Disposition: attachment; filename=smime.p7s
MIIBJgYJKoZIhvcNAQcCoIIBFzCCARMCAQExADALBgkqhkiG9w0BBwExgf4w
gfsCAQIwJjASMRAwDgYDVQQDEwdDYXJsUlNBAhBGNGvHgABWvBHTbi7EELOw
MAsGCWCGSAFlAwQCAaAxMC8GCSqGSIb3DQEJBDEiBCCxwpZGNZzTSsugsn+f
lEidzQK4mf/ozKqfmbxhcIkKqjALBgkqhkiG9w0BAQsEgYB0XJV7fjPa5Nuh
oth5msDfP8A5urYUMjhNpWgXG8ae3XpppqVrPi2nVO41onHnkByjkeD/wc31
A9WH8MzFQgSTsrJ65JvffTTXkOpRPxsSHn3wJFwP/atWHkh8YK/jR9bULhUl
Mv5jQEDiwVX5DRasxu6Ld8zv9u5/TsdBNiufGw==
------=_NextBoundary____Fri,_06_Sep_2002_00:25:21--
The content that is digested (the first part of the multipart/signed)
consists of the bytes:
54 68 69 73 20 69 73 20 73 6f 6d 65 20 73 61 6d 70 6c 65 20 63 6f 6e
74 65 6e 74 2e 0d 0a
3.6. 创建纯压缩消息
本节描述压缩 MIME 实体的格式。请注意,S/MIME 3.1 之前的版本未规定任何 CompressedData 的使用,也不会识别它。使用能力指示能够接收 CompressedData 在 [RFC3274] 中描述,是兼容性首选的方法。
步骤 1. 根据第 3.1 节准备要压缩的 MIME 实体。
步骤 2. 将 MIME 实体和其他所需数据处理为 CompressedData 类型的 CMS 对象。
步骤 3. 将 CompressedData 对象包裹在 CMS ContentInfo 对象中。
步骤 4. 将 ContentInfo 对象插入 application/pkcs7-mime MIME 实体。
纯压缩消息的 smime-type 参数为"compressed-data"。此类消息的文件扩展名为".p7z"。
示例消息如下:
Content-Type: application/pkcs7-mime; smime-type=compressed-data; name=smime.p7z Content-Transfer-Encoding: base64 Content-Disposition: attachment; filename=smime.p7z eNoLycgsVgCi4vzcVIXixNyCnFSF5Py8ktS8Ej0AlCkKVA==
3.7. 多重操作
纯签名、纯封装和纯压缩 MIME 格式可以嵌套。这之所以可行,是因为这些格式都是封装其他 MIME 实体的 MIME 实体。
S/MIME 实现 MUST 能够在收件人计算机的合理资源限制内接收和处理任意嵌套的 S/MIME。
可以按任意顺序应用签名、加密和压缩操作中的任何一种。由实现者和用户选择。先签名时,签名者随后被封装隐藏。先封装时,签名者暴露,但可以在不移除封装的情况下验证签名。这在希望自动验证签名的环境中很有用,因为验证签名不需要私钥材料。
选择先签名还是先加密存在安全后果。加密然后签名的消息的接收者可以验证加密块未被更改,但无法确定签名者与消息未加密内容之间的任何关系。签名然后加密的消息的接收者可以假定签名消息本身未被更改,但谨慎的攻击者可能更改了加密消息中未经认证的部分。
使用压缩时,请牢记以下准则:
- 不鼓励压缩以二进制数据传输的加密数据,因为它不会产生显著的压缩。以 base64 编码数据传输的加密数据也可能受益。
- 如果将有损压缩算法与签名一起使用,你需要先压缩,然后签名。
3.8. 创建证书管理消息
证书管理消息或 MIME 实体用于传输证书和/或证书撤销列表(CRL),例如响应注册请求。
步骤 1. 将证书和/或 CRL 提供给创建 SignedData 类型 CMS 对象的 CMS 生成过程。SignedData encapContentInfo eContent 字段 MUST 缺失,且 signerInfos 字段 MUST 为空。
步骤 2. 将 SignedData 对象包裹在 CMS ContentInfo 对象中。
步骤 3. 将 ContentInfo 对象封装在 application/pkcs7-mime MIME 实体中。
证书管理消息的 smime-type 参数为"certs-only"。此类消息的文件扩展名为".p7c"。
3.9. 注册请求
签名消息的发送代理 MUST 拥有用于签名的证书,以便接收代理可以验证签名。获取证书的方法有很多,例如通过与证书机构的交换、通过硬件令牌或软盘等。
S/MIME v2 [SMIMEv2] 规定了使用 application/pkcs10 主体部分向证书机构"注册"公钥的方法。此后,IETF PKIX 工作组开发了其他请求证书的方法。然而,S/MIME v4.0 不要求特定的证书请求机制。
3.10. 识别 S/MIME 消息
因为 S/MIME 考虑了非 MIME 环境中的互操作,采用了若干不同的机制来承载类型信息,识别 S/MIME 消息变得有些困难。下表列出了确定消息是否为 S/MIME 消息的标准。如果消息符合以下任一标准,则被视为 S/MIME 消息。
下表中文件后缀来自 Content-Type 头字段中的"name"参数或 Content-Disposition 头字段中的"filename"参数。承载文件后缀的 MIME 参数未在下方列出。
| 媒体类型 | 参数 | 文件后缀 |
|---|---|---|
| application/pkcs7-mime | N/A | N/A |
| multipart/signed | protocol="application/pkcs7-signature" | N/A |
| application/octet-stream | N/A | p7m, p7s, p7c, p7z |
4. 证书处理
接收代理 MUST 提供某种证书检索机制,以便获取数字信封收件人的证书。本规范不涵盖 S/MIME 代理如何处理证书——只涵盖在证书被验证或拒绝之后它们做什么。S/MIME 证书问题在 [RFC5750] 中涵盖。
至少,对于初始 S/MIME 部署,用户代理可以自动生成一条消息给目标收件人,请求以签名的返回消息提供该收件人的证书。接收和发送代理 SHOULD 还提供一种机制,允许用户"存储并保护"通信方的证书,以保证其后续检索。
4.1. 密钥对生成
所有密钥对 MUST 从良好的非确定性随机输入源 [RFC4086] 生成,且私钥 MUST 以安全方式保护。
S/MIME 用户代理 MUST NOT 生成小于 2048 位的非对称密钥用于 RSA 签名算法。
对于 2048 位至 4096 位带 SHA-256 的 RSA,见 [RFC5754] 和 [FIPS186-4]。第一个引用提供签名算法的 OID,第二个提供签名算法的定义。
对于 RSASSA-PSS with SHA-256,见 [RFC4056]。对于 RSAES-OAEP,见 [RFC3560]。
4.2. 签名生成
以下是 S/MIME 代理在生成 RSA 和 RSASSA-PSS 签名时的要求:
key size <= 2047 : SHOULD NOT (Note 2) 2048 <= key size <= 4096 : SHOULD (Note 1) 4096 < key size : MAY (Note 1) Note 1: 见第 6 节安全考量。 Note 2: 见附录 B 历史邮件考量。
ECDSA 和 EdDSA 的密钥长度由曲线固定。
4.3. 签名验证
以下是 S/MIME 接收代理在验证 RSA 和 RSASSA-PSS 签名时的要求:
key size <= 2047 : SHOULD NOT (Note 2) 2048 <= key size <= 4096 : MUST (Note 1) 4096 < key size : MAY (Note 1) Note 1: 见第 6 节安全考量。 Note 2: 见附录 B 历史邮件考量。
ECDSA 和 EdDSA 的密钥长度由曲线固定。
4.4. 加密
以下是 S/MIME 代理在使用 RSA 和 RSA-OAEP 算法为内容加密建立密钥时的要求:
key size <= 2047 : SHOULD NOT (Note 2) 2048 <= key size <= 4096 : SHOULD (Note 1) 4096 < key size : MAY (Note 1) Note 1: 见第 6 节安全考量。 Note 2: 见附录 B 历史邮件考量。
ECDH 的密钥长度由曲线固定。
4.5. 解密
以下是 S/MIME 代理在使用 RSA 和 RSAES-OAEP 算法为内容解密建立密钥时的要求:
key size <= 2047 : MAY (Note 2) 2048 <= key size <= 4096 : MUST (Note 1) 4096 < key size : MAY (Note 1) Note 1: 见第 6 节安全考量。 Note 2: 见附录 B 历史邮件考量。
ECDH 的密钥长度由曲线固定。
5. IANA 考量
本节 (1) 将 application/pkcs7-mime 和 application/pkcs7-signature 的媒体类型注册更新为引用本文档而非 RFC 5751,(2) 将 authEnveloped-data 添加到 smime-type 的值列表中,(3) 总体上将引用从 RFC 5751 更新为本文档。
注意其他文档可以为 S/MIME 定义附加的媒体类型。
5.1. application/pkcs7-mime 的媒体类型
类型名称(Type name): application
子类型名称(Subtype Name): pkcs7-mime
必需参数(Required Parameters): NONE
可选参数(Optional Parameters): smime-type
name
编码考量(Encoding Considerations): 见本文档第 3 节
安全考量(Security Considerations): 见本文档第 6 节
互操作考量(Interoperability Considerations): 见本文档第 1-6 节
已发布规范(Published Specification): RFC 2311, RFC 2633, RFC 5751,
and this document
使用此媒体类型的应用: Security applications
片段标识符考量(Fragment identifier considerations): N/A
附加信息(Additional information):
Deprecated alias names for this type: N/A
Magic number(s): N/A
File extensions(s): 见本文档第 3.2.1 节
Macintosh file type code(s): N/A
联系以获取更多信息的个人与邮箱地址:
The IESG <iesg@ietf.org>
预期用途(Intended usage): COMMON
使用限制(Restrictions on usage): NONE
作者(Author): Sean Turner
变更控制者(Change Controller): LAMPS working group delegated from the IESG
5.2. application/pkcs7-signature 的媒体类型
类型名称(Type name): application
子类型名称(Subtype Name): pkcs7-signature
必需参数(Required Parameters): N/A
可选参数(Optional Parameters): N/A
编码考量(Encoding Considerations): 见本文档第 3 节
安全考量(Security Considerations): 见本文档第 6 节
互操作考量(Interoperability Considerations): 见本文档第 1-6 节
已发布规范(Published Specification): RFC 2311, RFC 2633, RFC 5751,
and this document
使用此媒体类型的应用: Security applications
片段标识符考量(Fragment identifier considerations): N/A
附加信息(Additional information):
Deprecated alias names for this type: N/A
Magic number(s): N/A
File extensions(s): 见本文档第 3.2.1 节
Macintosh file type code(s): N/A
联系以获取更多信息的个人与邮箱地址:
The IESG <iesg@ietf.org>
预期用途(Intended usage): COMMON
使用限制(Restrictions on usage): N/A
作者(Author): Sean Turner
变更控制者(Change Controller): LAMPS working group delegated from the IESG
5.3. authEnveloped-data smime-type
IANA 已在"smime-type 参数的参数值"注册表中注册以下值。
smime-type value: authEnveloped-data Reference: RFC 8551, Section 3.2.2
5.4. 参考更新
IANA 要将所有对 RFC 5751 的引用更新为本文档。已知要更新的注册表是"CoAP Content-Formats"和"media-types"。
6. 安全考量
密码算法会随时间被攻破或削弱。实现者和用户需要检查本文档中列出的密码算法是否持续提供预期的安全级别。IETF 不时可能发布关于当前技术水平的文档。例如:
- RFC 3218 [RFC3218] 中描述的百万消息攻击(Million Message Attack)。
- RFC 2785 [RFC2785] 中描述的 Diffie-Hellman"小子群"攻击。
- RFC 4270 [RFC4270] 中描述的针对哈希算法的攻击。
本规范使用公钥密码技术。假设私钥受到保护,以确保其不被未授权方访问或更改。
大多数人或软件都无法估计消息内容的价值。此外,大多数人或软件都无法估计恢复用特定大小密钥加密的消息内容的实际成本。此外,如果收件人无法处理消息内容,确定解密失败的成本也相当困难。因此,对大多数人或软件而言,在不同密钥大小之间(或是否仅使用明文)进行选择也是不可能的。然而,基于这些标准的决策一直在做出,因此本规范提供了一个使用这些估计来选择算法的框架。
本规范中选择 2048 位作为 RSA 非对称密钥大小,是基于提供至少 100 位安全性的愿望。根据 [RFC3766],为符合本规范而必须支持的密钥大小对 Internet 似乎是合适的。当然,金融和医疗系统等环境可能选择不同的密钥大小。因此,实现 MAY 支持超出本规范推荐范围的密钥大小。
验证签名的接收代理和加密消息的发送代理在对使用大于本规范强制要求的密钥验证签名和加密消息时的密码处理使用需保持谨慎。攻击者可能发送带有会导致过多密码处理的密钥的证书——例如大于本规范强制要求的密钥,因为此类密钥可能淹没处理单元。建议在使用此类密钥之前未先将证书验证到信任锚的代理,具备某种密码资源管理机制以防止此类攻击。
某些密码算法(如 RC2)相比发送明文几乎不提供实际安全性。其他算法(如 TripleDES)提供安全性,但不再被视为当前最先进技术。S/MIME 要求使用当前最先进的算法(如 AES),并提供向通信对方宣布密码能力的能力。这允许发送者创建能够使用最强通用加密算法的消息。除非唯一的选择是没有密码学,否则绝不推荐使用 RC2 之类的算法。
小于 2048 位的 RSA 和 DSA 密钥现在被许多专家认为是密码学上不安全的(由于计算能力的进步),不应再用于保护消息。此类密钥先前被认为是安全的,因此处理先前接收的已签名和已加密邮件通常会导致使用弱密钥。希望支持先前版本 S/MIME 或处理旧消息的实现需要考虑较小密钥大小带来的安全风险(例如伪造消息)与服务拒绝成本之间的权衡。如果实现支持验证用小于 1024 位的 RSA 和 DSA 密钥生成的数字签名,它 MUST 警告用户。实现者应考虑为 newly received messages 和 previously stored messages 提供不同的警告。不适于用户警告的服务器实现(例如安全邮件列表服务器)SHOULD 拒绝带有弱签名的消息。
实现者 SHOULD 意识到多个活动密钥对可以与单个个人关联。例如,一个密钥对可用于支持机密性,而不同的密钥对可用于数字签名。
如果发送代理使用不同强度的密码学发送同一消息,监视通信信道的攻击者可能能够通过解密弱加密版本来确定强加密消息的内容。换句话说,发送者 SHOULD NOT 发送使用比原始消息更弱密码学的消息副本。
对 EnvelopedData 中密文的修改如果未同时使用认证,则可能无法被察觉,这就是在封装 EnvelopedData 时不将其包裹在 SignedData 中或不在其中包含 SignedData 时的情况。这是从 EnvelopedData 转向 AuthEnvelopedData 的原因之一,因为认证加密算法无需 SignedData 层即可提供认证。
如果实现关注是否符合美国国家标准与技术研究院(NIST)的密钥大小建议,则见 [SP800-57]。
如果消息环境利用消息已被签名这一事实来改变消息处理的行为(例如运行规则或 UI 显示提示),而未首先验证消息确实被签名并了解签名状态,这可能导致对消息的不正确处理。消息上的视觉指示符可能需要定期检查签名验证代码,如果该指示符旨在提供消息当前状态的信息。
许多人假设使用认证加密算法就足以对消息发送者进行认证。在几乎所有情况下,这都不是正确的陈述。认证加密算法提供此服务需要满足若干前提条件:
- 起始密钥必须绑定到单一实体。仅使用组密钥只能说明消息由持有该密钥的某个实体发送,但无法识别特定实体。
- 消息必须恰好有一个发送者和一个收件人。多于一个收件人将允许第二个收件人创建一条消息,使第一个收件人相信它来自发送者,方法是移除消息中的第二个收件人。
- 从起始密钥到用作 CEK 的密钥需要存在一条直接路径。该路径需要保证没有第三方能够看到所得的 CEK。这意味着需要使用在其他上下文中称为"Direct Encryption"或"Direct Key Agreement"的算法。这意味着起始密钥是(1)直接用作 CEK,或(2)用于创建密钥,然后通过 KDF 步骤转换为 CEK。
S/MIME 实现几乎普遍使用临时-静态而非静态-静态密钥协商,并且不使用共享密钥进行加密。这意味着第一个前提条件不满足。[RFC6278] 定义了如何将静态-静态密钥协商与 CMS 一起使用,因此第一个前提条件可以满足。目前,所有 S/MIME 密钥协商方法都派生一个密钥加密密钥(KEK)并包装一个 CEK。这违反了上述第三个前提条件。需要定义直接创建 CEK 而不创建中间 KEK 的新密钥协商算法。
即使满足了所有前提条件并通过使用认证加密算法确立了消息的起源,用户也需意识到无法向第三方证明这一点。这是因为任一方都可以基于 CEK 将为双方所知这一事实成功创建消息(或仅更改内容)。因此,起源性总是建立在"我没有给自己发送此消息"的假定之上。
本文档中所有认证加密算法在算法的加密部分都使用计数器模式(counter mode)。这意味着明文长度将始终可知,因为密文长度和明文长度总是相同。此信息可使被动观察者仅基于消息长度推断信息。对此关注的应用需要提供某种填充,以使消息长度不提供此信息。
当压缩与加密一起使用时,它有可能提供额外一层安全性。然而,在设计依赖使用压缩的协议时需谨慎,以免创建压缩预言机(compression oracle)。压缩预言机攻击需要对过程进行自适应输入,并基于压缩输出的长度攻击消息的未知内容。这意味着不一定需要对加密密钥进行攻击。
最近一篇关于 S/MIME 和 OpenPGP 电子邮件安全的论文 [Efail] 指出了当前 S/MIME 规范以及人们如何实现邮件客户端的一些问题。由于 CBC 模式操作方式的性质,这些模式允许明文的可塑性(malleability)。这种可塑性允许攻击者更改密文,并且如果知道部分明文,可创建任意明文块。这些更改可以在不触发 CBC 模式中弱完整性检查的情况下进行。这种类型的攻击可通过使用带有更健壮的完整性检查的关联数据认证加密(AEAD)算法来防止。因此,建议邮件系统尽快迁移到使用 AES-GCM,并且在完成完整性检查之前不应对解密内容采取行动。
[Efail] 中强调的另一个攻击是由于邮件客户端处理 HTML 和 multipart/mixed 消息的方式有误。客户端 MUST 要求 text/html 内容类型是完整的 HTML 文档(按 [RFC1866])。客户端 SHOULD 将 multipart/mixed 构造的不同部分视为不同来源。客户端 MUST 将 MIME 消息的每个已加密或已签名部分视为与未受保护内容以及彼此都来自不同来源。
7. 参考文献
7.1. 参考约定
[ASN.1] 指 [X.680]、[X.681]、[X.682]、[X.683]。
[CMS] 指 [RFC5083] 和 [RFC5652]。
[ESS] 指 [RFC2634] 和 [RFC5035]。
[MIME-SPEC] 指 [RFC2045]、[RFC2046]、[RFC2047]、[RFC2049]、[RFC6838] 和 [RFC4289]。
[SMIMEv2] 指 [RFC2311]、[RFC2312]、[RFC2313]、[RFC2314] 和 [RFC2315]。
[SMIMEv3] 指 [RFC2630]、[RFC2631]、[RFC2632]、[RFC2633]、[RFC2634] 和 [RFC5035]。
[SMIMEv3.1] 指 [RFC2634]、[RFC5035]、[RFC5652]、[RFC5750] 和 [RFC5751]。
[SMIMEv3.2] 指 [RFC2634]、[RFC3850]、[RFC3851]、[RFC3852] 和 [RFC5035]。
[SMIMEv4] 指 [RFC2634]、[RFC5035]、[RFC5652]、[RFC8550] 和本文档。
7.2. 规范性参考文献
[CHARSETS] IANA, "IANA 分配的字符集", http://www.iana.org/assignments/character-sets。
[FIPS186-4] National Institute of Standards and Technology (NIST), "数字签名标准(DSS)", Federal Information Processing Standards Publication 186-4, DOI 10.6028/NIST.FIPS.186-4, July 2013, https://nvlpubs.nist.gov/nistpubs/fips/nist.fips.186-4.pdf。
[RFC1847] Galvin, J., Murphy, S., Crocker, S., 和 N. Freed, "MIME 的安全多部分:Multipart/Signed 与 Multipart/Encrypted", RFC 1847, DOI 10.17487/RFC1847, October 1995, https://www.rfc-editor.org/info/rfc1847。
[RFC2045] Freed, N. 和 N. Borenstein, "多用途 Internet 邮件扩展(MIME)第一部分:Internet 消息主体格式", RFC 2045, DOI 10.17487/RFC2045, November 1996, https://www.rfc-editor.org/info/rfc2045。
[RFC2046] Freed, N. 和 N. Borenstein, "多用途 Internet 邮件扩展(MIME)第二部分:媒体类型", RFC 2046, DOI 10.17487/RFC2046, November 1996, https://www.rfc-editor.org/info/rfc2046。
[RFC2047] Moore, K., "MIME(多用途 Internet 邮件扩展)第三部分:非 ASCII 文本的消息头扩展", RFC 2047, DOI 10.17487/RFC2047, November 1996, https://www.rfc-editor.org/info/rfc2047。
[RFC2049] Freed, N. 和 N. Borenstein, "多用途 Internet 邮件扩展(MIME)第五部分:一致性标准与示例", RFC 2049, DOI 10.17487/RFC2049, November 1996, https://www.rfc-editor.org/info/rfc2049。
[RFC2119] Bradner, S., "用于 RFC 中以指示要求级别的关键词", BCP 14, RFC 2119, DOI 10.17487/RFC2119, March 1997, https://www.rfc-editor.org/info/rfc2119。
[RFC2183] Troost, R., Dorner, S., 和 K. Moore(编), "在 Internet 消息中传达呈现信息:Content-Disposition 头字段", RFC 2183, DOI 10.17487/RFC2183, August 1997, https://www.rfc-editor.org/info/rfc2183。
[RFC2634] Hoffman, P.(编), "S/MIME 的增强安全服务", RFC 2634, DOI 10.17487/RFC2634, June 1999, https://www.rfc-editor.org/info/rfc2634。
[RFC3274] Gutmann, P., "密码消息语法(CMS)的压缩数据内容类型", RFC 3274, DOI 10.17487/RFC3274, June 2002, https://www.rfc-editor.org/info/rfc3274。
[RFC3370] Housley, R., "密码消息语法(CMS)算法", RFC 3370, DOI 10.17487/RFC3370, August 2002, https://www.rfc-editor.org/info/rfc3370。
[RFC3560] Housley, R., "在密码消息语法(CMS)中使用 RSAES-OAEP 密钥传输算法", RFC 3560, DOI 10.17487/RFC3560, July 2003, https://www.rfc-editor.org/info/rfc3560。
[RFC3565] Schaad, J., "在密码消息语法(CMS)中使用高级加密标准(AES)加密算法", RFC 3565, DOI 10.17487/RFC3565, July 2003, https://www.rfc-editor.org/info/rfc3565。
[RFC4289] Freed, N. 和 J. Klensin, "多用途 Internet 邮件扩展(MIME)第四部分:注册流程", BCP 13, RFC 4289, DOI 10.17487/RFC4289, December 2005, https://www.rfc-editor.org/info/rfc4289。
[RFC4056] Schaad, J., "在密码消息语法(CMS)中使用 RSASSA-PSS 签名算法", RFC 4056, DOI 10.17487/RFC4056, June 2005, https://www.rfc-editor.org/info/rfc4056。
[RFC4086] Eastlake 3rd, D., Schiller, J., 和 S. Crocker, "安全的随机性要求", BCP 106, RFC 4086, DOI 10.17487/RFC4086, June 2005, https://www.rfc-editor.org/info/rfc4086。
[RFC5083] Housley, R., "CMS 认证-封装-数据内容类型", RFC 5083, DOI 10.17487/RFC5083, November 2007, https://www.rfc-editor.org/info/rfc5083。
[RFC5084] Housley, R., "在密码消息语法(CMS)中使用 AES-CCM 和 AES-GCM 认证加密", RFC 5084, DOI 10.17487/RFC5084, November 2007, https://www.rfc-editor.org/info/rfc5084。
[RFC5652] Housley, R., "密码消息语法(CMS)", STD 70, RFC 5652, DOI 10.17487/RFC5652, September 2009, https://www.rfc-editor.org/info/rfc5652。
[RFC5753] Turner, S. 和 D. Brown, "在密码消息语法(CMS)中使用椭圆曲线密码(ECC)算法", RFC 5753, DOI 10.17487/RFC5753, January 2010, https://www.rfc-editor.org/info/rfc5753。
[RFC5754] Turner, S., "在密码消息语法中使用 SHA2 算法", RFC 5754, DOI 10.17487/RFC5754, January 2010, https://www.rfc-editor.org/info/rfc5754。
[RFC6838] Freed, N., Klensin, J., 和 T. Hansen, "媒体类型规范与注册流程", BCP 13, RFC 6838, DOI 10.17487/RFC6838, January 2013, https://www.rfc-editor.org/info/rfc6838。
[RFC8174] Leiba, B., "RFC 2119 关键词中大写与小写的歧义", BCP 14, RFC 8174, DOI 10.17487/RFC8174, May 2017, https://www.rfc-editor.org/info/rfc8174。
[RFC8418] Housley, R., "在密码消息语法(CMS)中将椭圆曲线 Diffie-Hellman 密钥协商算法与 X25519 和 X448 一起使用", RFC 8418, DOI 10.17487/RFC8418, August 2018, https://www.rfc-editor.org/info/rfc8418。
[RFC8419] Housley, R., "在密码消息语法(CMS)中使用 Edwards 曲线数字签名算法(EdDSA)签名", RFC 8419, DOI 10.17487/RFC8419, August 2018, https://www.rfc-editor.org/info/rfc8419。
[RFC8550] Schaad, J., Ramsdell, B., 和 S. Turner, "安全/多用途 Internet 邮件扩展(S/MIME)版本 4.0 证书处理", RFC 8550, DOI 10.17487/RFC8550, April 2019, https://www.rfc-editor.org/info/rfc8550。
[X.680] "信息技术 - 抽象语法记法一(ASN.1):基本记法规范", ITU-T 建议 X.680, ISO/IEC 8824-1:2015, August 2015, https://www.itu.int/rec/T-REC-X.680。
[X.681] "信息技术 - 抽象语法记法一(ASN.1):信息对象规范", ITU-T 建议 X.681, ISO/IEC 8824-2:2015, August 2015, https://www.itu.int/rec/T-REC-X.681。
[X.682] "信息技术 - 抽象语法记法一(ASN.1):约束规范", ITU-T 建议 X.682, ISO/IEC 8824-3:2015, August 2015, https://www.itu.int/rec/T-REC-X.682。
[X.683] "信息技术 - 抽象语法记法一(ASN.1):ASN.1 规范的参数化", ITU-T 建议 X.683, ISO/IEC 8824-4:2015, August 2015, https://www.itu.int/rec/T-REC-X.683。
[X.690] "信息技术 - ASN.1 编码规则:基本编码规则(BER)、规范编码规则(CER)和可分辨编码规则(DER)规范", ITU-T 建议 X.690, ISO/IEC 8825-1:2015, August 2015, https://www.itu.int/rec/T-REC-X.690。
7.3. 资料性参考文献
[Efail] Poddebniak, D., Dresen, C., Muller, J., Ising, F., Schinzel, S., Friedberger, S., Somorovsky, J., 和 J. Schwenk, "Efail:利用外泄通道攻破 S/MIME 和 OpenPGP 电子邮件加密", UsenixSecurity 2018, August 2018, https://www.usenix.org/system/files/conference/usenixsecurity18/sec18-poddebniak.pdf。
[FIPS186-2] National Institute of Standards and Technology (NIST), "数字签名标准(DSS)(含变更通知 1)", Federal Information Processing Standards Publication 186-2, January 2000, https://csrc.nist.gov/publications/detail/fips/186/2/archive/2000-01-27。
[RFC1866] Berners-Lee, T. 和 D. Connolly, "超文本标记语言 - 2.0", RFC 1866, DOI 10.17487/RFC1866, November 1995, https://www.rfc-editor.org/info/rfc1866。
[RFC2268] Rivest, R., "RC2(r) 加密算法的描述", RFC 2268, DOI 10.17487/RFC2268, March 1998, https://www.rfc-editor.org/info/rfc2268。
[RFC2311] Dusse, S., Hoffman, P., Ramsdell, B., Lundblade, L., 和 L. Repka, "S/MIME 版本 2 消息规范", RFC 2311, DOI 10.17487/RFC2311, March 1998, https://www.rfc-editor.org/info/rfc2311。
[RFC2312] Dusse, S., Hoffman, P., Ramsdell, B., 和 J. Weinstein, "S/MIME 版本 2 证书处理", RFC 2312, DOI 10.17487/RFC2312, March 1998, https://www.rfc-editor.org/info/rfc2312。
[RFC2313] Kaliski, B., "PKCS #1:RSA 加密版本 1.5", RFC 2313, DOI 10.17487/RFC2313, March 1998, https://www.rfc-editor.org/info/rfc2313。
[RFC2314] Kaliski, B., "PKCS #10:证书请求语法版本 1.5", RFC 2314, DOI 10.17487/RFC2314, March 1998, https://www.rfc-editor.org/info/rfc2314。
[RFC2315] Kaliski, B., "PKCS #7:密码消息语法版本 1.5", RFC 2315, DOI 10.17487/RFC2315, March 1998, https://www.rfc-editor.org/info/rfc2315。
[RFC2630] Housley, R., "密码消息语法", RFC 2630, DOI 10.17487/RFC2630, June 1999, https://www.rfc-editor.org/info/rfc2630。
[RFC2631] Rescorla, E., "Diffie-Hellman 密钥协商方法", RFC 2631, DOI 10.17487/RFC2631, June 1999, https://www.rfc-editor.org/info/rfc2631。
[RFC2632] Ramsdell, B.(编), "S/MIME 版本 3 证书处理", RFC 2632, DOI 10.17487/RFC2632, June 1999, https://www.rfc-editor.org/info/rfc2632。
[RFC2633] Ramsdell, B.(编), "S/MIME 版本 3 消息规范", RFC 2633, DOI 10.17487/RFC2633, June 1999, https://www.rfc-editor.org/info/rfc2633。
[RFC2785] Zuccherato, R., "避免针对 S/MIME 的 Diffie-Hellman 密钥协商方法的"小子群"攻击的方法", RFC 2785, DOI 10.17487/RFC2785, March 2000, https://www.rfc-editor.org/info/rfc2785。
[RFC3218] Rescorla, E., "防止针对密码消息语法的百万消息攻击", RFC 3218, DOI 10.17487/RFC3218, January 2002, https://www.rfc-editor.org/info/rfc3218。
[RFC3766] Orman, H. 和 P. Hoffman, "为用于交换对称密钥的公钥确定强度", BCP 86, RFC 3766, DOI 10.17487/RFC3766, April 2004, https://www.rfc-editor.org/info/rfc3766。
[RFC3850] Ramsdell, B.(编), "安全/多用途 Internet 邮件扩展(S/MIME)版本 3.1 证书处理", RFC 3850, DOI 10.17487/RFC3850, July 2004, https://www.rfc-editor.org/info/rfc3850。
[RFC3851] Ramsdell, B.(编), "安全/多用途 Internet 邮件扩展(S/MIME)版本 3.1 消息规范", RFC 3851, DOI 10.17487/RFC3851, July 2004, https://www.rfc-editor.org/info/rfc3851。
[RFC3852] Housley, R., "密码消息语法(CMS)", RFC 3852, DOI 10.17487/RFC3852, July 2004, https://www.rfc-editor.org/info/rfc3852。
[RFC4134] Hoffman, P.(编), "S/MIME 消息示例", RFC 4134, DOI 10.17487/RFC4134, July 2005, https://www.rfc-editor.org/info/rfc4134。
[RFC4270] Hoffman, P. 和 B. Schneier, "Internet 协议中对密码哈希的攻击", RFC 4270, DOI 10.17487/RFC4270, November 2005, https://www.rfc-editor.org/info/rfc4270。
[RFC4949] Shirey, R., "Internet 安全术语表,第 2 版", FYI 36, RFC 4949, DOI 10.17487/RFC4949, August 2007, https://www.rfc-editor.org/info/rfc4949。
[RFC5035] Schaad, J., "增强安全服务(ESS)更新:增加 CertID 算法灵活性", RFC 5035, DOI 10.17487/RFC5035, August 2007, https://www.rfc-editor.org/info/rfc5035。
[RFC5750] Ramsdell, B. 和 S. Turner, "安全/多用途 Internet 邮件扩展(S/MIME)版本 3.2 证书处理", RFC 5750, DOI 10.17487/RFC5750, January 2010, https://www.rfc-editor.org/info/rfc5750。
[RFC5751] Ramsdell, B. 和 S. Turner, "安全/多用途 Internet 邮件扩展(S/MIME)版本 3.2 消息规范", RFC 5751, DOI 10.17487/RFC5751, January 2010, https://www.rfc-editor.org/info/rfc5751。
[RFC6151] Turner, S. 和 L. Chen, "MD5 消息摘要与 HMAC-MD5 算法的更新安全考量", RFC 6151, DOI 10.17487/RFC6151, March 2011, https://www.rfc-editor.org/info/rfc6151。
[RFC6194] Polk, T., Chen, L., Turner, S., 和 P. Hoffman, "SHA-0 和 SHA-1 消息摘要算法的安全考量", RFC 6194, DOI 10.17487/RFC6194, March 2011, https://www.rfc-editor.org/info/rfc6194。
[RFC6268] Schaad, J. 和 S. Turner, "密码消息语法(CMS)与使用 X.509 的公钥基础设施(PKIX)的附加新 ASN.1 模块", RFC 6268, DOI 10.17487/RFC6268, July 2011, https://www.rfc-editor.org/info/rfc6268。
[RFC6278] Herzog, J. 和 R. Khazan, "在密码消息语法中使用静态-静态椭圆曲线 Diffie-Hellman 密钥协商", RFC 6278, DOI 10.17487/RFC6278, June 2011, https://www.rfc-editor.org/info/rfc6278。
[RFC7114] Leiba, B., "创建 smime-type 参数值的注册表", RFC 7114, DOI 10.17487/RFC7114, January 2014, https://www.rfc-editor.org/info/rfc7114。
[RFC7905] Langley, A., Chang, W., Mavrogiannopoulos, N., Strombergson, J., 和 S. Josefsson, "传输层安全(TLS)的 ChaCha20-Poly1305 密码套件", RFC 7905, DOI 10.17487/RFC7905, June 2016, https://www.rfc-editor.org/info/rfc7905。
[SP800-56A] National Institute of Standards and Technology (NIST), "使用离散对数密码学的成对密钥建立方案建议", NIST Special Publication 800-56A Revision 2, DOI 10.6028/NIST.SP.800-56Ar2, May 2013, https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-56Ar2.pdf。
[SP800-57] National Institute of Standards and Technology (NIST), "密钥管理建议 - 第 1 部分:通用", NIST Special Publication 800-57 Revision 4, DOI 10.6028/NIST.SP.800-57pt1r4, January 2016, https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-57pt1r4.pdf。
[TripleDES] Tuchman, W., "Hellman 指出 DES 没有捷径解决方案", IEEE Spectrum v. 16, n. 7, pp. 40-41, DOI 10.1109/MSPEC.1979.6368160, July 1979。
附录 A. ASN.1 模块
注:本文包含的 ASN.1 模块与 RFC 5751 [SMIMEv2] 和 RFC 3851 [SMIMEv3.1] 相比未做更改,唯一的例外是 RFC 3851 [SMIMEv3.1] 中 preferBinaryInside 的 ASN.1 注释有所更改。如果需要与当前 ASN.1 标准兼容的模块,可以在 [RFC6268] 中找到。本模块使用 1988 版本的 ASN.1。
SecureMimeMessageV3dot1
{ iso(1) member-body(2) us(840) rsadsi(113549)
pkcs(1) pkcs-9(9) smime(16) modules(0) msg-v3dot1(21) }
DEFINITIONS IMPLICIT TAGS ::=
BEGIN
IMPORTS
-- Cryptographic Message Syntax [CMS]
SubjectKeyIdentifier, IssuerAndSerialNumber,
RecipientKeyIdentifier
FROM CryptographicMessageSyntax
{ iso(1) member-body(2) us(840) rsadsi(113549)
pkcs(1) pkcs-9(9) smime(16) modules(0) cms-2001(14) };
-- id-aa is the arc with all new authenticated and unauthenticated
-- attributes produced by the S/MIME Working Group.
id-aa OBJECT IDENTIFIER ::= {iso(1) member-body(2) usa(840)
rsadsi(113549) pkcs(1) pkcs-9(9) smime(16) attributes(2)}
-- S/MIME Capabilities provides a method of broadcasting the
-- symmetric capabilities understood. Algorithms SHOULD be ordered
-- by preference and grouped by type.
smimeCapabilities OBJECT IDENTIFIER ::= {iso(1) member-body(2)
us(840) rsadsi(113549) pkcs(1) pkcs-9(9) 15}
SMIMECapability ::= SEQUENCE {
capabilityID OBJECT IDENTIFIER,
parameters ANY DEFINED BY capabilityID OPTIONAL }
SMIMECapabilities ::= SEQUENCE OF SMIMECapability
-- Encryption Key Preference provides a method of broadcasting the
-- preferred encryption certificate.
id-aa-encrypKeyPref OBJECT IDENTIFIER ::= {id-aa 11}
SMIMEEncryptionKeyPreference ::= CHOICE {
issuerAndSerialNumber [0] IssuerAndSerialNumber,
receipentKeyId [1] RecipientKeyIdentifier,
subjectAltKeyIdentifier [2] SubjectKeyIdentifier
}
-- "receipentKeyId" is spelled incorrectly but is kept for
-- historical reasons.
id-smime OBJECT IDENTIFIER ::= { iso(1) member-body(2) us(840)
rsadsi(113549) pkcs(1) pkcs-9(9) 16 }
id-cap OBJECT IDENTIFIER ::= { id-smime 11 }
-- The preferBinaryInside OID indicates an ability to receive
-- messages with binary encoding inside the CMS wrapper.
-- The preferBinaryInside attribute's value field is ABSENT.
id-cap-preferBinaryInside OBJECT IDENTIFIER ::= { id-cap 1 }
-- The following is a list of OIDs to be used with S/MIME v3.
-- Signature Algorithms Not Found in [RFC3370], [RFC5754], [RFC4056],
-- and [RFC3560]
--
-- md2WithRSAEncryption OBJECT IDENTIFIER ::=
-- {iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) pkcs-1(1)
-- 2}
--
-- Other Signed Attributes
--
-- signingTime OBJECT IDENTIFIER ::=
-- {iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) pkcs-9(9)
-- 5}
-- See [CMS] for a description of how to encode the attribute
-- value.
SMIMECapabilitiesParametersForRC2CBC ::= INTEGER
-- (RC2 Key Length (number of bits))
END
附录 B. 历史邮件考量
在更新 S/MIME 规范的过程中,每次文档更新都会修改推荐的算法集合。这意味着如果用户拥有历史电子邮件,而他们的用户代理已更新为仅支持当前推荐的算法集合,那么其中一些旧电子邮件将不再可访问。强烈建议用户代理实现以下部分算法以处理历史电子邮件。
本附录包含若干对被废弃或替换的文档的引用。这是有意为之,因为更新后的文档通常不再包含相同的信息。
B.1. DigestAlgorithmIdentifier
以前的 S/MIME 规范曾指出以下算法需要某种程度的支持:
- SHA-1 在 [SMIMEv4] 中被移除。SHA-1 不再被认为是安全的,因为它不再具有抗碰撞性。IETF 关于 SHA-1 的声明见 [RFC6194],但相对于最新进展已经过时。
- MD5 在 [SMIMEv4] 中被移除。MD5 不再被认为是安全的,因为它不再具有抗碰撞性。详情见 [RFC6151]。
B.2. 签名算法
验证足够古老的消息上的签名存在若干困难。因此,强烈建议用户代理将这些签名与当前消息上的签名区别对待。这些问题包括以下内容:
- 证书机构不要求在证书过期后的一次更新之外将证书保留在 CRL 上。这意味着除非 CRL 作为消息的一部分被缓存,否则并不总是能够检查证书是否已被撤销。在线证书状态协议(OCSP)响应也存在相同的问题,因为它们可能基于 CRL 而非证书数据库。
- 小于 2048 位的 RSA 和 DSA 密钥现在被许多专家认为是密码学上不安全的(由于计算能力的进步)。此类密钥先前被认为是安全的,因此处理历史签名消息通常会使用弱密钥。希望支持先前版本 S/MIME 或处理旧消息的实现需要考虑较小密钥大小带来的安全风险(例如伪造消息)与服务拒绝成本之间的权衡。
- 用于验证历史消息签名的哈希函数可能不再被认为是安全的(见下文)。虽然目前还没有已知的针对 MD5 或 SHA-1 的实用原像或二次原像攻击,但它们不再被认为具有抗碰撞性这一事实意味着签名的安全级别通常被认为是可疑的。如果已知某消息是历史的,并且客户端已持有它一段时间,那么它可能仍被认为是安全的。
- 前两个问题同样适用于用于验证将公钥绑定到签名消息身份所用的证书。
以前的 S/MIME 规范曾指出以下算法需要某种程度的支持:
- RSA with MD5 在 [SMIMEv4] 中被移除。MD5 不再被认为是安全的,因为它不再具有抗碰撞性。详情见 [RFC6151]。
- RSA and DSA with SHA-1 在 [SMIMEv4] 中被移除。SHA-1 不再被认为是安全的,因为它不再具有抗碰撞性。IETF 关于 SHA-1 的声明见 [RFC6194],但相对于最新进展已经过时。
- DSA with SHA-256 在 [SMIMEv4] 中被移除。DSA 已被椭圆曲线版本取代。
由于"强制实现"的要求随时间发生了变化,产生了若干可能导致互操作问题的情形:
- S/MIME v2 客户端只被要求使用 rsaEncryption 算法配合 SHA-1 或 MD5 验证数字签名,并且可能完全不实现 id-dsa-with-sha1 或 id-dsa。
- S/MIME v3 客户端可能只实现使用 id-dsa-with-sha1 的签名或签名验证,并且可能在此字段中使用 id-dsa 作为 AlgorithmIdentifier。
- 注意,S/MIME v3.1 客户端支持验证 id-dsa-with-sha1 和 rsaEncryption,但可能不实现 sha256WithRSAEncryption。
注意:接收客户端 SHOULD 将 id-dsa 识别为与 id-dsa-with-sha1 等价。
对于 512 位 RSA with SHA-1,见 [RFC3370] 和 [FIPS186-2](不含变更通知 1);对于 512 位 RSA with SHA-256,见 [RFC5754] 和 [FIPS186-2](不含变更通知 1);对于 1024 位至 2048 位 RSA with SHA-256,见 [RFC5754] 和 [FIPS186-2](含变更通知 1)。第一个引用提供签名算法的 OID,第二个提供签名算法的定义。
对于 512 位 DSA with SHA-1,见 [RFC3370] 和 [FIPS186-2](不含变更通知 1);对于 512 位 DSA with SHA-256,见 [RFC5754] 和 [FIPS186-2](不含变更通知 1);对于 1024 位 DSA with SHA-1,见 [RFC3370] 和 [FIPS186-2](含变更通知 1);对于 1024 位及以上的 DSA with SHA-256,见 [RFC5754] 和 [FIPS186-4]。第一个引用提供签名算法的 OID,第二个提供签名算法的定义。
B.3. ContentEncryptionAlgorithmIdentifier
以前的 S/MIME 规范曾指出以下算法需要某种程度的支持:
- RC2/40 [RFC2268] 在 [SMIMEv3.2] 中被移除。该算法已知是不安全的,如果支持,只应用于解密现有电子邮件。
- DES EDE3 CBC [TripleDES],也称为"tripleDES",在 [SMIMEv4] 中被移除。该算法从支持的算法列表中移除,因为(1)它具有 64 位分组大小,(2)它提供少于 128 位的安全性。该算法应该只支持用于解密现有电子邮件;不应将其用于加密新电子邮件。
B.4. KeyEncryptionAlgorithmIdentifier
以前的 S/MIME 规范曾指出以下算法需要某种程度的支持:
- 如 [RFC3370] 和 [SP800-57] 规定的 DH 临时-静态模式,在 [SMIMEv4] 中被移除。
- RSA 密钥大小随时间而增加。使用较小密钥大小解密旧邮件是合理的;但是,新邮件应使用更新后的密钥大小。
对于 1024 位 DH,见 [RFC3370]。对于 1024 位及以上的 DH,见 [SP800-56A];无论如何,使用来自 X9.42 的 KDF,其在 [RFC3370] 中指定。
附录 C. 将 S/MIME v2 消息规范移至历史状态
S/MIME v3 [SMIMEv3]、v3.1 [SMIMEv3.1] 和 v3.2 [SMIMEv3.2] 规范与 S/MIME v2 消息规范 [SMIMEv2] 向后兼容,例外在于算法(移除了 RC2/40 要求并增加了 DSA 和 RSASSA-PSS 要求)。因此,RFC 2311 [SMIMEv2] 被移至历史状态。
致谢
非常感谢 S/MIME 版本 2 消息规范 RFC 的其他作者:Steve Dusse、Paul Hoffman、Laurence Lundblade 和 Lisa Repka。没有 v2,就不会有 v3、v3.1、v3.2 或 v4.0。
本文档中的一些示例复制自 [RFC4134]。感谢在该文档中编写并验证这些示例的人们。
S/MIME 工作组的许多成员也付出了非常艰辛的努力并为本文档做出了贡献。任何人员名单都注定会有遗漏,对此我表示歉意。按字母顺序,以下人员在我脑海中尤为突出,因为他们为本文档做出了直接贡献:
Tony Capel、Piers Chivers、Dave Crocker、Bill Flanigan、Peter Gutmann、Alfred Hoenes、Paul Hoffman、Russ Housley、William Ottaway 和 John Pawling。
S/MIME 文档的版本 4 更新是在 LAMPS 工作组的赞助下完成的。
作者地址
Jim Schaad
August Cellars
Email: ietf@augustcellars.com
Blake Ramsdell
Brute Squad Labs, Inc.
Email: blaker@gmail.com
Sean Turner
sn3rd
Email: sean@sn3rd.com
