TLS握手未完成

问题描述

我有一个带有自签名证书的客户端和服务器应用程序。 do_handshake方法无法正常工作。在客户端中,SSL协商成功完成,但在服务器上未成功完成。服务器一直在说before SSL initialization(使用get_state_string())。

查看代码。 客户

from OpenSSL import SSL,crypto
import socket

HOST = "localhost"
PORT = 8080

def verify_cb(conn,cert,errnum,depth,ok):
    print(f"Got certificate: %s {cert.get_subject()}")
    print(f"Issued by: {cert.get_issuer()}")
    return ok

# Initialise SSL context:
ctx = SSL.Context(SSL.TLSv1_2_METHOD)
ctx.set_verify(SSL.VERIFY_PEER,verify_cb) # Demand a server certificate
ctx.load_verify_locations("serverpath.pem")
ctx.use_privatekey_file('clientkey.pem')
ctx.use_certificate_file('clientpath.pem')

# Set up client:
sock = SSL.Connection(ctx,socket.socket(socket.AF_INET,socket.soCK_STREAM))

sock.connect((HOST,PORT))
sock.set_connect_state()
print(sock.get_state_string())
while True:
    try:
        sock.do_handshake()
        break
    except SSL.WantReadError:
        pass
print(sock.get_state_string())
sock.write("HELLO")

# Read response:
while True:
    try:
        print(sock.recv(4096))
    except SSL.ZeroReturnError:
        break

服务器

from OpenSSL import SSL,verify_cb) # Demand a client certificate
ctx.load_verify_locations("clientpath.pem")
ctx.use_privatekey_file('serverkey.pem')
ctx.use_certificate_file('serverpath.pem')
# Set up sever:
sock = SSL.Connection(ctx,socket.soCK_STREAM))
sock.setsockopt(socket.soL_SOCKET,socket.so_REUSEADDR,1)
sock.bind((HOST,PORT))
sock.listen(1)

print("Waiting for connections.")

#Wait for clients to connect:
(conn,address) = sock.accept()
sock.set_accept_state()
print(f"Got connection from {address}")
print(sock.get_state_string())
while True:
    try:
        print(sock.get_state_string())
        print(conn.recv(4096))
        print(sock.get_state_string())
    except SSL.ZeroReturnError:
        break

请,有人可以告诉我我在做什么错吗?

解决方法

(conn,address) = sock.accept()
sock.set_accept_state()
print(f"Got connection from {address}")
print(sock.get_state_string())
while True:
    try:
        print(sock.get_state_string())
        print(conn.recv(4096))
        print(sock.get_state_string())

您需要在接受的套接字conn上而不是服务器套接字sock上进行操作。从接受的套接字读取时,将打印服务器套接字的状态,而不反映连接的套接字的状态。另外,由于您已经在SSL服务器套接字上调用了accept,因此不需要设置接受状态:

(conn,address) = sock.accept()
print(f"Got connection from {address}")
print(conn.get_state_string())
while True:
    try:
        print(conn.get_state_string())
        print(conn.recv(4096))
        print(conn.get_state_string())

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...