我想问一下TLS如何决定密钥交换算法(曲线选择)。
客户端和服务器之间的通信是通过TLS进行的。服务器与客户端在同一台计算机上运行,并且都可以访问相同的证书。客户端和服务器呼叫SSL_CTX_set_cipher_list设置密码到ECDHE-ECDSA-AES128-GCM-SHA256。
在通信期间应用的证书和密钥是使用ecparam name_curve secp521r1创建的。
当调用服务器SSL_CTX_set_ecdh_auto一切工作就好了。但是,当服务器尝试曲线限制secp521r1,通过调用SSL_CTX_set1_curves_list,客户端无法连接。 看来,该曲线secp521r1不用于ECDHE。
我的问题是为什么?
答案 0 :(得分:0)
我喜欢用这个web site来描述TLS协议。
当一个客户端初始连接时,它发送一个“客户端Hello”分组。数据包中包含“受支持的密码套件”部分(请参阅RFC的A.5)。如果服务器不支持任何受支持的密码套件,则它将在该点拒绝连接。
从7.4.1.2。的客户端Hello的RFC:
在加密套件列表中,从所述客户端在
传递到服务器 ClientHello消息,包含密码的组合
客户端支持的算法,按客户端的顺序排列
偏好(喜欢选择第一)。每个密码套件定义了一个关键
交换算法,批量加密算法(包括密钥) 长度),MAC算法和PRF。服务器将选择一个密码 套房或者,如果没有可接受的选择都,返回一个握手
故障警报并关闭连接。如果列表中包含密码
套房服务器不承认,支持,或希望使用的
服务器必须忽略那些密码套件,以及处理剩余
像往常一样。
因此,很可能您已将服务器选项限制为客户端不支持的选项。如果客户端支持ECDHE-ECDSA-AES128-GCM-SHA256,则它应该可以工作。我还假设您没有禁用其他必需的密码套件(例如,大容量加密算法等)
更新: 我不能说我了解发生了什么,但是通过openssl源代码查看,在我能找到的任何选项中,SSL_CTX_set1_curves_list API均未暴露于openssl命令行。
的OpenSSL确实露出"-named_curve"选项:
-named_curve曲线指定要使用的椭圆曲线。注意:这是一条曲线,而不是列表。
请注意:这允许影响服务器不是客户端
这使用SSL_CTX_set_tmp_ecdh / SSL_set_tmp_ecdh API。在您上面所说的限制ECDH选项时,这对我来说更有意义。我通常暴露这个API到我在服务器端的选项。