RFC 8732 | GSS Keyex SHA-2 | February 2020 |
Sorce & Kario | Standards Track | [Page] |
本文档详细说明了 RFC 4462 的补充和修订。 它定义了一种新的密钥交换方法,该方法使用 SHA-2 来保证完整性,并弃用弱 Diffie-Hellman (DH) 组。 本规范的目的是实现通用安全服务 (GSS) 密钥交换所使用的加密原语的现代化。¶
这是一份互联网标准跟踪文档。¶
本文档是互联网工程任务组 (IETF) 的产品。 它代表了IETF社区的共识。 它已接受公众审查,并已被互联网工程指导小组 (IESG) 批准发布。 有关互联网标准的更多信息,请参阅 RFC 7841 第 2 节。¶
有关本文档当前状态、任何勘误表以及如何提供反馈的信息,请访问 https://www.rfc-editor.org/info/rfc8732。¶
版权所有 (c) 2020 IETF Trust 和文档作者。 保留所有权利。¶
本文档受本文档发布之日生效的 BCP 78 和 IETF Trust 与 IETF 文件相关的法律规定 (https://trustee.ietf.org/license-info) 的约束。 请仔细阅读这些文件,因为它们描述了您与本文件相关的权利和限制。 从本文档中提取的代码组件必须包含信托法律条款第 4.e 节中所述的简化 BSD 许可文本,并且在提供时不提供简化 BSD 许可中所述的保证。¶
安全外壳 (SSH) 通用安全服务应用程序编程接口 (GSS-API) 方法 [RFC4462] 允许使用 GSS-API [RFC2743] 用于 SSH 中的身份验证和密钥交换。 [RFC4462]定义了三种基于DH组和SHA-1的交换方法。 本文档使用新方法更新了 [RFC4462],旨在支持希望使用 SHA-2 加密哈希函数的环境。¶
由于 SHA-1 [RFC6194] 和少于 2048 位的模幂 (MODP) 组的安全问题[NIST-SP-800 -131Ar2],我们建议使用基于 SHA-2 [RFC6234] 的哈希值以及 DH group14、group15、group16、group17,和 group18 [RFC3526]。 此外,我们还添加了对基于椭圆曲线 Diffie-Hellman 与 NIST P-256、P-384 和 P-521 [SEC2v2] 的密钥交换的支持如 X25519 和 X448 [RFC7748] 曲线。 按照[RFC8268]的做法,DH组仅使用SHA-256和SHA-512哈希值。 对于 NIST 曲线,为了一致性,采用与 [RFC5656] 中使用的相同的曲线到哈希算法配对。¶
关键字“必须”、“不得”、“必需”、“应当”、“不应"、"应该"、"不应"、"推荐"、"不推荐本文档中的“”、“可以”和“可选0>”应按照 BCP 14 [RFC2119 中的描述进行解释t12>]1> [RFC81744>]3> 当且仅当它们全部大写出现时,如此处所示。¶5>
本文档采用 [RFC4462] 中定义的相同命名约定来定义涵盖与特定 Diffie-Hellman 组和 SHA-2 一起使用的任何 GSS-API 机制的方法系列哈希组合。¶
Key Exchange Method Name | Implementation Recommendations |
---|---|
gss-group14-sha256-* | SHOULD/RECOMMENDED |
gss-group15-sha512-* | MAY/OPTIONAL |
gss-group16-sha512-* | SHOULD/RECOMMENDED |
gss-group17-sha512-* | MAY/OPTIONAL |
gss-group18-sha512-* | MAY/OPTIONAL |
每个密钥交换方法前缀都由该文档注册。 IESG 是所有这些密钥交换方法的变更控制器;这并不意味着 IESG 被认为控制着相应的 GSS-API 机制。¶
任何方法系列中的每种方法(表 2)均指定 GSS-API 验证的 Diffie-Hellman 密钥交换,如 [RFC4462 的 第 2.1 节 中所述]。 每个方法的方法名称(表 1)是系列名称前缀与 MD5 哈希值 [RFC1321] 的 Base64 编码的串联相应 GSS-API 机制 OID 的 ASN.1 DER 编码 [ISO-IEC-8825-1] 的值。 Base64 编码在 [RFC4648] 的 Section 4 中描述。¶
Family Name Prefix | Hash Function | Group | Reference |
---|---|---|---|
gss-group14-sha256- | SHA-256 | 2048-bit MODP | Section 3 of [RFC3526] |
gss-group15-sha512- | SHA-512 | 3072-bit MODP | Section 4 of [RFC3526] |
gss-group16-sha512- | SHA-512 | 4096-bit MODP | Section 5 of [RFC3526] |
gss-group17-sha512- | SHA-512 | 6144-bit MODP | Section 6 of [RFC3526] |
gss-group18-sha512- | SHA-512 | 8192-bit MODP | Section 7 of [RFC3526] |
在[RFC5656]中,介绍了基于椭圆曲线密码学的新SSH密钥交换算法。 我们重用 [RFC5656] 的第 4 节 的大部分内容来定义 GSS-API 验证的椭圆曲线 Diffie-Hellman (ECDH) 密钥交换。¶
此外,我们还利用 [RFC8731] 中定义的曲线来补充 [RFC5656] 所需的三个经典 NIST 定义的曲线.¶
本节重用了 [RFC4462] 的第 2.1 节 中定义的大部分方案,并将其与 中定义的方案结合起来[RFC5656] 第 4 节;特别是,[RFC5656]第 4 节中规定的所有检查和验证步骤也适用于此处。¶
密钥协商方案“ECDHE-Curve25519”和“ECDHE-Curve448”分别使用函数X25519和X448执行Diffie-Hellman协议。 实现必须使用[RFC7748]中描述的算法计算这些函数。 当他们这样做时,实现必须检查计算出的 Diffie-Hellman 共享密钥是否为全零值,如果是则中止,如第 6 节中所述[RFC7748]。 Alternative implementations of these functions SHOULD abort when either the client or the server input forces the shared secret to one of a small set of values, as described in Sections 6 and 7 of [RFC7748].¶
本节遵循 [RFC7546] 作为 GSS-API 上下文建立操作的信息来源,其中 3 节最为相关。 [RFC7546] 中描述的所有安全注意事项也适用于此处。¶
根据 [SEC1v2] 第 3.2.1 节,双方各自生成一个临时密钥对。 双方收到密钥后根据 [SEC1v2] 第 3.2.3.1 节进行验证。¶
对于 NIST 曲线,密钥使用未压缩的点表示,并且必须使用[SEC1v2]第 2.3.4 节中的算法进行转换。 如果转换失败或使用压缩表示传输点,则密钥交换必须失败。¶
GSS上下文根据[RFC5656]的Section 4建立;客户端使用GSS_Init_sec_context()发起建立,服务器使用GSS_Accept_sec_context()响应它。 对于协商,客户端必须将mutual_req_flag和integ_req_flag设置为“true”。 此外,如果用户请求,deleg_req_flag可以设置为“true”以请求访问授权。 由于密钥交换过程仅验证主机,因此 anon_req_flag 的设置对此过程无关紧要。 如果客户端不支持 [RFC4462] 的第 4 节中描述的“gssapi-keyex”用户身份验证方法,或者不打算支持将该方法与密钥交换期间建立的 GSS-API 上下文结合使用,然后 anon_req_flag 应该 设置为“true”。 否则,如果客户端希望隐藏其身份,则此标志可以设置为“true”。 一旦上下文建立,这个密钥交换过程将仅交换单个消息词符;因此,replay_det_req_flag和sequence_req_flag应该设置为“false”。¶
在此过程中,客户端必须将其公钥包含在其发送到服务器的第一条消息中;如果服务器收到多个密钥或根本没有收到密钥,则密钥交换必须失败。¶
在GSS上下文建立期间,客户端和服务器可以交换多个 Token 。 当 GSS 上下文建立时(major_status 为 GSS_S_COMPLETE),各方检查mutual_state 和 integ_avail 是否均为“true”。 如果不是,密钥交换必须失败。¶
一旦一方收到对等方的公钥,它就会继续计算共享秘密 K。对于 NIST 曲线,计算是根据 [SEC1v2] 的第 3.3.1 节完成的,并且使用 [SEC1v2] 第 2.3.5 节中定义的转换将结果值 z 转换为八位字节字符串 K。 对于 curve25519 和 curve448,改用 [RFC7748] 的 Section 6 中的算法。¶
为了验证握手的完整性,对等方使用所选密钥交换方法定义的哈希函数来计算 H:¶
H = 哈希(V_C || V_S || I_C || I_S || K_S || Q_C || Q_S || K)。¶
服务器使用 GSS_GetMIC() 调用(以 H 作为负载)来生成消息完整性代码 (MIC)。 客户端使用 GSS_VerifyMIC() 调用来验证 MIC。¶
如果任何 GSS_Init_sec_context() 或 GSS_Accept_sec_context() 返回除 GSS_S_COMPLETE 或 GSS_S_CONTINUE_NEEDED 之外的 Major_status,或者任何其他 GSS-API 调用返回除 GSS_S_COMPLETE 之外的 Major_status,则密钥交换必须失败。 关于错误报告,遵循 [RFC4462] 的第 2.1 节 中表达的相同建议。¶
以下是密钥交换过程的概述:¶
Client Server ------ ------ Generates ephemeral key pair. Calls GSS_Init_sec_context(). SSH_MSG_KEXGSS_INIT ---------------> Verifies received key. (Optional) <------------- SSH_MSG_KEXGSS_HOSTKEY (Loop) | Calls GSS_Accept_sec_context(). | <------------ SSH_MSG_KEXGSS_CONTINUE | Calls GSS_Init_sec_context(). | SSH_MSG_KEXGSS_CONTINUE ------------> Calls GSS_Accept_sec_context(). Generates ephemeral key pair. Computes shared secret. Computes hash H. Calls GSS_GetMIC( H ) = MIC. <------------ SSH_MSG_KEXGSS_COMPLETE Verifies received key. Computes shared secret. Computes hash H. Calls GSS_VerifyMIC( MIC, H ).¶
这是通过以下消息实现的:¶
客户端发送:¶
byte SSH_MSG_KEXGSS_INIT string output_token (from GSS_Init_sec_context()) string Q_C, client's ephemeral public key octet string¶
服务器可能会响应:¶
byte SSH_MSG_KEXGSS_HOSTKEY string server public host key and certificates (K_S)¶
服务器发送:¶
byte SSH_MSG_KEXGSS_CONTINUE string output_token (from GSS_Accept_sec_context())¶
每次客户端收到上述消息时,都会再次调用 GSS_Init_sec_context()。¶
客户端发送:¶
byte SSH_MSG_KEXGSS_CONTINUE string output_token (from GSS_Init_sec_context())¶
作为最终消息,如果生成了output_token,服务器将发送以下内容:¶
byte SSH_MSG_KEXGSS_COMPLETE string Q_S, server's ephemeral public key octet string string mic_token (MIC of H) boolean TRUE string output_token (from GSS_Accept_sec_context())¶
如果没有产生output_token,服务器发送:¶
byte SSH_MSG_KEXGSS_COMPLETE string Q_S, server's ephemeral public key octet string string mic_token (MIC of H) boolean FALSE¶
哈希 H 被计算为以下各项串联的 HASH 哈希:¶
string V_C, the client's version string (CR, NL excluded) string V_S, server's version string (CR, NL excluded) string I_C, payload of the client's SSH_MSG_KEXINIT string I_S, payload of the server's SSH_MSG_KEXINIT string K_S, server's public host key string Q_C, client's ephemeral public key octet string string Q_S, server's ephemeral public key octet string mpint K, shared secret¶
该值称为“交换哈希”,用于验证密钥交换。 交换哈希应该保密。 如果服务器未发送或客户端未接收到 SSH_MSG_KEXGSS_HOSTKEY 消息,则在计算交换哈希时将使用空字符串代替 K_S。¶
由于此密钥交换方法不需要将主机密钥用于任何加密操作,因此 SSH_MSG_KEXGSS_HOSTKEY 消息是可选。 如果使用 [RFC4462] 的第 5 节 中描述的“空”主机密钥算法,则此消息不得 被发送。¶
如果客户端在调用 GSS_Init_sec_context() 返回了 Major_status 代码 GSS_S_COMPLETE 后收到 SSH_MSG_KEXGSS_CONTINUE 消息,则发生协议错误,并且密钥交换必须失败。¶
如果客户端收到 SSH_MSG_KEXGSS_COMPLETE 消息,并且对 GSS_Init_sec_context() 的调用未导致 Major_status 代码为 GSS_S_COMPLETE,则发生协议错误,并且密钥交换必须失败。¶
Key Exchange Method Name | Implementation Recommendations |
---|---|
gss-nistp256-sha256-* | SHOULD/RECOMMENDED |
gss-nistp384-sha384-* | MAY/OPTIONAL |
gss-nistp521-sha512-* | MAY/OPTIONAL |
gss-curve25519-sha256-* | SHOULD/RECOMMENDED |
gss-curve448-sha512-* | MAY/OPTIONAL |
每个密钥交换方法前缀都由该文档注册。 IESG 是所有这些密钥交换方法的变更控制器;这并不意味着 IESG 被认为控制着相应的 GSS-API 机制。¶
任何方法系列中的每种方法(表 4)都指定 GSS-API 验证的椭圆曲线 Diffie-Hellman 密钥交换,如第 5.1 节中所述。 每个方法的方法名称(表 3)是系列方法名称与 MD5 哈希的 Base64 编码的串联 [RFC1321]相应 GSS-API 机制 OID 的 ASN.1 DER 编码 [ISO-IEC-8825-1] 的值。 Base64 编码在 [RFC4648] 的 Section 4 中描述。¶
Family Name Prefix | Hash Function | Parameters / Function Name | Definition |
---|---|---|---|
gss-nistp256-sha256- | SHA-256 | secp256r1 | Section 2.4.2 of [SEC2v2] |
gss-nistp384-sha384- | SHA-384 | secp384r1 | Section 2.5.1 of [SEC2v2] |
gss-nistp521-sha512- | SHA-512 | secp521r1 | Section 2.6.1 of [SEC2v2] |
gss-curve25519-sha256- | SHA-256 | X22519 | Section 5 of [RFC7748] |
gss-curve448-sha512- | SHA-512 | X448 | Section 5 of [RFC7748] |
由于它们的密钥长度较小并且在面对暴力攻击时不再强大,因此下表中的算法被视为已弃用并且不应使用。¶
Key Exchange Method Name | Implementation Recommendations |
---|---|
gss-group1-sha1-* | SHOULD NOT |
gss-group14-sha1-* | SHOULD NOT |
gss-gex-sha1-* | SHOULD NOT |
本文档扩充了 [RFC4462] 中定义的 SSH 密钥交换消息名称(请参阅第 6 节); IANA 已将此文档列为“SSH 协议参数”[IANA-KEX-NAMES] 注册表中这些条目的参考。¶
此外,IANA 还更新了注册表,以包含 4 和 5 节中描述的 SSH 密钥交换消息名称。¶
Key Exchange Method Name | Reference |
---|---|
gss-group1-sha1-* | RFC 8732 |
gss-group14-sha1-* | RFC 8732 |
gss-gex-sha1-* | RFC 8732 |
gss-group14-sha256-* | RFC 8732 |
gss-group15-sha512-* | RFC 8732 |
gss-group16-sha512-* | RFC 8732 |
gss-group17-sha512-* | RFC 8732 |
gss-group18-sha512-* | RFC 8732 |
gss-nistp256-sha256-* | RFC 8732 |
gss-nistp384-sha384-* | RFC 8732 |
gss-nistp521-sha512-* | RFC 8732 |
gss-curve25519-sha256-* | RFC 8732 |
gss-curve448-sha512-* | RFC 8732 |
除了使用不同的安全哈希函数和更大的 DH 组之外,[RFC4462] 描述的协议没有进行重大更改;因此,所有最初的安全考虑都适用。¶
尽管这些方法使用了新的加密原语,但实际的密钥交换严格遵循[RFC5656]中定义的密钥交换;因此,所有最初的安全考虑因素以及 [RFC5656] 中表达的安全考虑因素均适用。¶
当设置了 deleg_req_flag 时,某些 GSS-API 机制可以对请求进行操作,将凭证委托给目标主机。 在这种情况下,必须格外小心,以确保正在验证的接受者与用户预期的目标相匹配。 某些机制实现(例如常用的 krb5 库)可能会使用不安全的 DNS 解析来规范化目标名称;在这些情况下,欺骗指向攻击者控制的计算机的 DNS 响应可能会导致用户默默地将凭据委托给攻击者,然后攻击者可以随意冒充用户。¶