首页 > 解决方案 > TLS - 用于 ECDHE 的曲线

问题描述

我想问一下 TLS 如何决定密钥交换算法(曲线选择)。

客户端和服务器之间的通信是通过 TLS 进行的。服务器与客户端在同一台计算机上运行,​​并且都可以访问相同的证书。客户端和服务器都调用 SSL_CTX_set_cipher_list 将密码设置为 ECDHE-ECDSA-AES128-GCM-SHA256。

通信期间应用的证书和密钥是使用 ecparam name_curve secp521r1 创建的。

当服务器调用 SSL_CTX_set_ecdh_auto 一切正常。但是,当服务器尝试通过调用 SSL_CTX_set1_curves_list 将曲线限制为 secp521r1 时,客户端无法连接。似乎曲线 secp521r1 不用于 ECDHE。

我的问题是为什么?

标签: openssltls1.2ecdh

解决方案


我喜欢用这个网站来描述 TLS 协议。

当客户端最初连接时,它会发送一个“Client Hello”数据包。数据包中包含“支持的密码套件”部分(参见RFC的 A.5 )。如果服务器不支持任何受支持的密码套件,那么它将在那时拒绝连接。

从 7.4.1.2。RFC的客户您好:


在ClientHello 消息中从客户端传递到服务器的密码套件列表包含
客户端支持的密码算法的组合,这些组合按客户端的
偏好排列(最喜欢的选择在前)。每个密码套件都定义了一个密钥
交换算法、一个批量加密算法(包括密钥长度)、一个 MAC 算法和一个 PRF。服务器将选择一个密码套件,或者,如果没有提供可接受的选择,则返回握手
失败警报并关闭连接。如果列表包含
服务器不识别、不支持或不希望使用的密码套件,服务器必须忽略这些密码套件,并 像往常一样
处理剩余的密码套件。

因此,您很可能已将服务器选项限制为客户端不支持的选项。如果客户端支持 ECDHE-ECDSA-AES128-GCM-SHA256,它应该可以工作。我还假设您没有禁用其他所需的密码套件(例如批量加密算法等)

更新:我不能说我明白发生了什么,但通过 openssl 源代码查看,SSL_CTX_set1_curves_list API 在我能找到的任何选项中都不会暴露给 openssl 命令行。

openssl 确实公开了“-named_curve”选项:

-named_curve curve 指定要使用的椭圆曲线。注意:这是单曲线,不是列表。

注意:这允许影响服务器而不是客户端。

这使用SSL_CTX_set_tmp_ecdh / SSL_set_tmp_ecdh API。在您上面谈论的限制ECDH选项的内容中,这对我来说更有意义。我通常将此 API 公开给我在服务器端的选项。


推荐阅读