python TLS套接字中的TLS会话恢复

问题描述 投票:2回答:2

我在python中有一个简单的TLS客户端连接到TLS服务器。我无法控制服务器。即使我最近访问过它,我也需要与每台服务器进行全新的TLS握手。

1)默认情况下,非浏览器TLS客户端(如以下python客户端)是否执行会话恢复?

2)我怎么知道他们是否这样做?如果在后台执行会话,如何禁用会话恢复?

请注意,我为每个连接到的新域创建一个新套接字。

import socket, ssl

context = ssl.SSLContext() 
context.verify_mode = ssl.CERT_NONE 
context.check_hostname = False 

mycipher = "DHE-RSA-AES128-SHA"
context.set_ciphers(mycipher) 
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 
domain = "google.com"
mySocket = context.wrap_socket(sock, server_hostname = domain) 
mySocket.connect((domain, 443))
mySocket.close()
python-3.x sockets session ssl tls1.2
2个回答
1
投票

这是一个困难但有趣的问题。而且你确实使用了适当的术语TLS,它带给我快乐;-)

首先,看看会话恢复在TLS1.3中发生了变化,所以这可能会影响你未来的事情(至少在命名之前,TLS1.3之前这个功能更多地讲述了会话和门票,而TLS1.3更喜欢谈论一个预共享密钥):https://timtaubert.de/blog/2017/02/the-future-of-session-resumption/

现在关于你的问题:

1)默认情况下,非浏览器TLS客户端(如以下python客户端)是否执行会话恢复?

  1. https://docs.python.org/3.7/library/ssl.html的Python文档没有说“恢复”;如果它什么都没说,我会假定它根本就没有这样做。但它确实谈到了可能是同义词的“缓存”。
  2. 实际上你可以在https://docs.python.org/3.7/library/ssl.html#ssl.SSLSession注意到会话具有以下属性:ticket_lifetime_hinthas_ticket;这应该与恢复有关。
  3. 现在看看https://docs.python.org/3.7/library/ssl.html#ssl.SSLContext.options,如果你浏览所有可能的值,你得到: ssl.OP_NO_TICKET防止客户端请求会话票证。
  4. 因此,我在1)中的假设可能是错误的,并且您默认会话恢复。您应该使用上面的选项禁用它
  5. (恰恰相反)它似乎存在于PyOpenSSL(仅对股票ssl),因为这里有一个关于如何为该库禁用此功能的问题:How to disable session resumption in pyOpenSSL?
  6. 根据经验,您可以尝试通过以这样的方式运行应用程序来发现它,即它在关闭时间内连接两次到同一端点,并查看交换的TLS消息类型。例如,在TLS 1.3中(应该与其他版本类似,但某些名称可能会更改),新的握手从ClientHello / ServerHello开始,其中恢复以相同的消息开始但具有pre_shared_key扩展名。它的存在将显示TLS恢复。在TLS 1.2中,客户端将在恢复握手期间发送SessionTicketextension。

2)我怎么知道他们是否这样做?如果在后台执行会话,如何禁用会话恢复?

  1. 如果我对上述内容是正确的,请确保在SSL上下文对象中使用ssl.OP_NO_TICKET。否则,默认情况下它是OP_ALL,它是一组各种选项,旨在最大限度地提高互操作性,但内容可能会根据您的Python版本和使用的基础OpenSSL库而改变。
  2. 如果你的会话填充了has_ticket属性,我猜它会使用TLS恢复或设置为使用它。

0
投票

1)默认情况下,非浏览器TLS客户端(如以下python客户端)是否执行会话恢复?

默认情况下,python tls / ssl库不执行会话恢复。

2)我怎么知道他们是否这样做?如果在后台执行会话,如何禁用会话恢复?

您可以使用以下代码验证是否未发生会话恢复:

import socket
import ssl

hostname = 'www.stackoverflow.com'
context = ssl.create_default_context()

# Create a new socket, then create a secure socket
sock = socket.create_connection((hostname, 443))
ssock = context.wrap_socket(sock, server_hostname=hostname)

# Was the TLS Session re-used?
print(ssock.session_reused) # False
© www.soinside.com 2019 - 2024. All rights reserved.