我需要通过 python 模拟 tls 重新协商行为(我将其理解为新的握手)。这可能吗?
我尝试了下面的代码,第一个 do_handshake 有效,但第二个什么都不做。
import socket, ssl, pprint, re, time
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
ssl_sock = ssl.wrap_socket(s,ca_certs="cacert.pem",do_handshake_on_connect=False)
ssl_sock.connect(('172.18.7.162', 443))
time.sleep(3)
ssl_sock.do_handshake()
print repr(ssl_sock.getpeername())
print ssl_sock.cipher()
print pprint.pformat(ssl_sock.getpeercert())
send_content="aaaa"
ssl_sock.write(send_content)
time.sleep(2)
print "do_handshake_again"
ssl_sock.do_handshake()
print "do_handshake_again done"
ssl_sock.write(send_content)
感谢您的帮助!
最佳答案
回答我自己的问题: 最后,我使用 python openssl lib 实现了这个行为。
from OpenSSL import SSL
import sys, os, select, socket
........
# Initialize context
ctx = SSL.Context(SSL.SSLv23_METHOD)
ctx.set_options(SSL.OP_NO_SSLv2)
#ctx.set_verify(SSL.VERIFY_PEER|SSL.VERIFY_FAIL_IF_NO_PEER_CERT, verify_cb) # Demand a certificate
ctx.use_privatekey_file (os.path.join(dir, 'server.pkey'))
ctx.use_certificate_file(os.path.join(dir, 'server.cert'))
ctx.load_verify_locations(os.path.join(dir, 'CA.cert'))
# Set up server
server = SSL.Connection(ctx, socket.socket(socket.AF_INET, socket.SOCK_STREAM))
server.bind(('', int(sys.argv[1])))
server.listen(3)
server.setblocking(0)
........
for cli in w:
try:
ret = cli.send(writers[cli])
cli.renegotiate()
cli.do_handshake()
ret = cli.send(writers[cli])
......
重要的是最后4行: 1、用socket发送东西 2-3、触发重新协商并握手 4、再发点东西
因为它是非阻塞套接字,我可以看到这段代码发送了两个数据包:第一个数据包将只发送应用程序数据(内容类型 23),第二个数据包将有两个有效负载:一个是 ssl 握手(类型 22)另一个是应用程序数据(类型 23)。
顺便说一句,这是在尝试模拟重新协商数据包在同一数据包中包含应用程序数据。如果对于纯 tls 重新协商,我们可以使用 openssl 发送“R”来触发纯 tls 重新协商行为。
关于python - 如何通过 python ssl 套接字进行 tls 重新协商,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31713302/