我正试图找到一种方法来防止基于OpenSSL的服务器(1.0.2g)要求客户端从TLS1.0移动到TLS1.2。
这是一个专有服务器。我需要通过openssl直接通过openssl API调用,OP标志,编译选项等来完成这个。
我无权修改连接到我服务器的客户端。这个特定的客户端目前包含了一定比例的流量到我的服务器,但有一个错误导致它在协商后有效挂起。
如果我的服务器是针对较早版本的OpenSSL(例如1.0.0d)编译的,那么服务器不会尝试将协议提交到TLS1.2,将其保留在TLS1.0,并且一切都工作正常。< / p>
出于安全原因,我需要迁移到最新版本的OpenSSL。有没有办法阻止服务器要求客户端使用TLS1.0移动到TLS1.2,同时仍允许TLS1.2客户端继续使用TLS1.2?
(这些旧客户已被弃用,最终会消失。默认情况下,新客户已经在TLS1.2进入)
答案 0 :(得分:3)
阻止TLS版本协商......
发生了根本性的误解。 TLS版本不协商本身。
当发送ClientHello
时,有一个版本的TLS就是这个版本。客户端的TLS协议版本通常称为ClientHello.client_version
。还有ServerHello
和ServerHello.server_version
。
来自RFC 5246, The Transport Layer Security (TLS) Protocol Version 1.2,第40页:
struct {
ProtocolVersion client_version;
Random random;
SessionID session_id;
CipherSuite cipher_suites<2..2^16-2>;
CompressionMethod compression_methods<1..2^8-1>;
select (extensions_present) {
case false:
struct {};
case true:
Extension extensions<0..2^16-1>;
};
} ClientHello;
假设客户端完全有能力,客户端应该尝试TLS 1.2。如果服务器连接失败,则客户端尝试TLS 1.1。如果服务器连接失败,则客户端尝试TLS 1.0。
多客户端重试正是浏览器所做的事情,以及TLS_FALLBACK_SCSV
来自RFC 7507, TLS Fallback Signaling Cipher Suite Value (SCSV) for Preventing Protocol Downgrade Attacks的原因。 TLS_FALLBACK_SCSV
允许客户端检测攻击者何时试图强制降级连接。
在实践中发生的事情是记录层和有效负载层。记录层承载TLS有效负载,并允许在没有该功能的传输上进行分段。客户端使用SSLv3记录层,以便它通过功能最少的中间件盒和TLS 1.2有效载荷层(来自握手问候语)以获得更强的加密。某些服务器将其解释为客户端能够通过TLS v1.2进行SSL v3.0。
为了使水更加泥泞,还有与压缩相关的版本,当它可用时。所以可以有三个不同的版本。
我试图找到一种方法来阻止基于OpenSSL的服务器(1.0.2g)要求客户端从TLS1.0移动到TLS1.2。
好的,鉴于上面的讨论,服务器不会提出任何问题。如果客户在其ClientHello.client_version
中宣传TLS v1.2,那么该服务器通过在其ServerHello.server_version
中使用相同版本进行回复来使用该内容。
我认为您可以使用以下内容来获取所需内容。但是你需要对此进行全面测试,因为我怀疑它会导致相当多的互操作问题:
// Record and payload layer
const SSL_METHOD* method = TLSv1_method();
SSL_CTX* context = SSL_CTX_new(method);
...
以上是OpenSSL的测试程序s_client
和s_server
在执行openssl s_client -connect ... -tls
之类的操作时所执行的操作。您可以在<openssl src dir>/apps
中找到源代码。
如果您使用SSLv23_method
,那么您将获得与SSLv2兼容的ClientHello
,并且您需要执行Jim向您展示的内容。
另请参阅OpenSSL wiki上的SSL/TLS Client。
这里是使用TLS 1.0的HTTPS连接的样子。使用openssl s_client -connect www.yahoo.com:443 -tls1 -servername www.yahoo.com
创建了对Yahoo的跟踪。我使用的是Yahoo而不是Stack Overflow,因为我需要一个新的连接。
答案 1 :(得分:1)
您在SSL_CTX_new上使用了什么?
你可以
SSL_CTX_new(SSLv23_method())
然后
SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3)
现在只支持TLS 1.0的客户端将使用TLS 1.0。可以支持TLS 1.2的客户端将与TLS 1.2协商。这不是你想要的吗?
我没试过,但你可能会:
SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3 | SSL_OP_NO_TLSv1_1)
消除了任何TLS 1.1,只留下1.0或1.2作为选项。
答案 2 :(得分:0)
假设您可以访问源代码中的SSL_CTX
,则以下内容应禁用TLS 1.2的支持/提供:
SSL_CTX *ssl_ctx;
...
#ifdef SSL_OP_NO_TLSv1_2
/* Disable TLSv1.2 */
SSL_CTX_set_options(ssl_ctx, SSL_OP_NO_TLSv1_2);
#endif
同样,如果您因任何原因需要禁用TLSv1.1的提供/使用,您可以使用SSL_OP_NO_TLSv1_1
选项(并且,根据您的OpenSSL版本,类似#ifdef
防护)。
希望这有帮助!