那么有没有办法在建立连接之前知道服务器正在运行哪个协议?
没有。但是您现在应该假定它的“TLS 1.0 及更高版本”。
正如 Steffen 所指出的,您使用 SSLv23_method 和上下文选项来实现“TLS 1.0 及更高版本”。这是完整的代码。您可以在客户端或服务器中使用它:
const SSL_METHOD* method = SSLv23_method();
if(method == NULL) handleFailure();
SSL_CTX* ctx = SSL_CTX_new(method);
if(ctx == NULL) handleFailure();
const long flags = SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3 | SSL_OP_NO_COMPRESSION;
SSL_CTX_set_options(ctx, flags);
现在,这里有一个不太明显的隐含假设;这个假设是错误的。该假设是存在“TLS min”和“TLS max”版本。
发生的情况是存在承载协议有效负载的底层 SSL/TLS 记录层。 TLS 记录层独立于协议层,有自己的版本。人们将 TLS 记录层版本解释为“TLS min”版本;协议版本为“TLS max”版本。大多数客户端服务器、站点和服务都以这种方式使用它。
但是,IETF 并未以这种方式指定它,浏览器也不会以这种方式使用它。因此,我们最近收到了TLS Fallback Signaling Cipher Suite Value (SCSV)。
浏览器是正确的。这是它应该如何完成的:
- 尝试 TLS 1.2,使用 Fallback Signaling 检测降级攻击
- 如果 TLS 1.2 失败,则尝试 TLS 1.1,使用 Fallback Signaling 检测降级攻击
- 如果 TLS 1.1 失败,则尝试 TLS 1.0,使用 Fallback Signaling 检测降级攻击
许多人在 TLS 1.0 失败后放弃了。一些用户代理可能会继续使用 SSLv3。
为什么 IETF 没有向我们提供“TLS min”和“TLS max”?这仍然是个谜。我认为给出的有效论点是“假设客户端想要使用 TLS 1.0、1.2 和 1.3,而不是 1.1”。我不知道有谁会放弃这样的协议版本,所以它对我来说只是个稻草人。 (这是我想知道执法部门或国家利益(如 NSA)是否在篡改标准的时候之一。
该问题最近再次在 TLS 工作组中提出。来自TLS: prohibit <1.2 support on 1.3+ servers (but allow clients)(2015 年 5 月 21 日):
现在可能是为 TLS 1.3 添加 (3) 的好时机:拥有一个客户端
指定他们愿意使用的最低 TLS 版本,以及
他们希望使用的最强大的 TLS。而MAC还是从它派生出来的吧
不可篡改或降级。
您仍然可以提供 TLS 记录层版本,并且您可以
保持它未经过 MAC 处理,以便它可以被篡改以导致泄露或
崩溃:)
实际上,记录层和客户端中的版本就是这样
正在使用协议。它阻止了浏览器和那些愚蠢的舞蹈
其他用户代理无需 TLS Fallback SCSV 即可执行。
如果 IETF 的部分使命是记录现有实践,那么 IETF 并未履行其使命。