Python SSL не может подключиться к серверу TLS1.2 с клиентом TLS1.2 - PullRequest
0 голосов
/ 20 января 2019

Я работаю на сокете python3 + сервер ssl, чтобы использовать его для обмена данными между сервером и клиентом.Я создал клиент, который работает с Google.com, python.org и моим собственным веб-сервером apache2.

Когда я запускаю свой сервер и пытаюсь подключиться через open ssl с openssl s_client -connect myserver.com:8443, он возвращает:

    CONNECTED(00000003)
    140035580617152:error:1408F10B:SSL routines:ssl3_get_record:wrong version number:../ssl/record/ssl3_record.c:252:
    ---
    no peer certificate available
    ---
    No client certificate CA names sent
    ---
    SSL handshake has read 5 bytes and written 176 bytes
    Verification: OK
    ---
    New, (NONE), Cipher is (NONE)
    Secure Renegotiation IS NOT supported
    Compression: NONE
    Expansion: NONE
    No ALPN negotiated
    SSL-Session:
        Protocol  : TLSv1.2
        Cipher    : 0000
        Session-ID: 
        Session-ID-ctx: 
        Master-Key: 
        PSK identity: None
        PSK identity hint: None
        SRP username: None
        Start Time: 1547929149
        Timeout   : 7200 (sec)
        Verify return code: 0 (ok)
        Extended master secret: no
    ---

Я не уверен в этом, но похоже, что TLSv1.2 поддерживается.Когда я пытаюсь подключиться к нему с помощью своего клиента, я получаю следующую ошибку

    Traceback (most recent call last):
      File "client-1.py", line 38, in <module>
        sock.connect((HOST, PORT))
      File "/usr/lib/python3.6/ssl.py", line 1109, in connect
        self._real_connect(addr, False)
      File "/usr/lib/python3.6/ssl.py", line 1100, in _real_connect
        self.do_handshake()
      File "/usr/lib/python3.6/ssl.py", line 1077, in do_handshake
        self._sslobj.do_handshake()
      File "/usr/lib/python3.6/ssl.py", line 689, in do_handshake
        self._sslobj.do_handshake()
    ssl.SSLError: [SSL: WRONG_VERSION_NUMBER] wrong version number (_ssl.c:847)

. Странная часть - это когда я использую свой клиент для подключения, например, к своему собственному серверу apache2 (с ssl)он возвращает TLSv1.2, что действительно заставляет меня задаться вопросом, заключается ли проблема в моем клиенте или в моем сервере

Я уже пытался использовать разные версии TLS / SSL на сервере и клиенте, но ни одна из них не работала такдалеко.Еще одна вещь, которую я пытался обновить, - это обновление OpenSSL, и по состоянию на 19.01.2009 он находится в самой последней версии, доступной в Ubuntu 18.04

Мой сервер выглядит следующим образом

import socket
import sys
from _thread import *
import ssl

context = ssl.SSLContext()
ssl.PROTOCOL_TLS_SERVER
#context.load_cert_chain(certfile="ssl/localhost/localhost.crt", keyfile="ssl/localhost/localhost.key")
context.load_cert_chain(certfile="ssl/certificate.crt", keyfile="ssl/private.key")


host = ''
port = 8443
print(port)

buffer = 134217700 #128 MiB

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)




def log_client_to_file(ip, port, data, file):
    #context manager
    with open(file, 'a') as f:
        f.write("User sent data from:\n\tIP: %s\n\tPort: %s\nData:\n%s\n\n" % (ip, port, data))

    #close file
    f.close()

def conn_process(buffer):
    data_tmp = conn.recv(buffer)
    data = str.encode('')
    while len(data_tmp) > 2:
        data += data_tmp
        data_tmp = conn.recv(buffer
        if len(data_tmp) < 2:
            data += data_tmp
            break
    return data

try:
    s.bind((host,port))
except socket.error as e:
    print(str(e))


s.listen(4)


print('Server is up and waiting for connection')
def client_threaded(conn, ip, port, file):
    conn.send(str.encode('Connected'))

    while True:

        data = conn_process(buffer)

        reply = 'Server output: %s' % data.decode('utf-8')
        if not data:
            break
        conn.sendall(str.encode(reply))
        log_client_to_file(ip, port, data, file)

while True:
    conn, addr = s.accept()
    print('connected to: %s:%s' % (addr[0], str(addr[1])))


    start_new_thread(client_threaded, (conn, addr[0], str(addr[1]), 'connections.log'))

s.close()


s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

Теперь,мой клиент построен следующим образом:

import socket
import ssl

HOST = 'myserver.com'
PORT = 8443


args = ssl.SSLContext()
ssl.PROTOCOL_TLS_CLIENT
args.verify_mode = ssl.CERT_NONE
args.check_hostname = False
#ssl.ca_certs="ssl/ca_bundle.crt",

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock = args.wrap_socket(s, server_hostname=HOST)

sock.connect((HOST, PORT))

print(sock.version())

Примечание: поскольку я работаю с самозаверяющими сертификатами в целях тестирования, я еще не проверяю их

Поскольку клиент и сервер используютTLS Я ожидал, что соединение не будет проблемой, но я продолжаю получать вышеупомянутую ошибку ssl.SSLError: [SSL: WRONG_VERSION_NUMBER] wrong version number (_ssl.c:847), которая удивляет меня, так как я не могу найти никаких ошибок.Может быть, вы, ребята, знаете, что я делаю неправильно и как я могу это исправить

Обратите внимание, я использую Python 3.6 и OpenSSL 1.1.0g 2 ноября 2017

1 Ответ

0 голосов
/ 20 января 2019

Я не уверен в этом, но похоже, что TLSv1.2 поддерживается.

Нет, это не так.

... ssl3_get_record:wrong version number:../ssl/record/ssl3_record.c:252:
...
SSL handshake has read 5 bytes and written 176 bytes
...
   Protocol  : TLSv1.2
   Cipher    : 0000

Это показывает, что клиенты запускают рукопожатие TLS с ClientHello (176 байт) и получают только 5 байт от сервера,что является слишком коротким для ожидаемого ответа в рукопожатии TLS.И эти 5 байтов не содержат номер версии TLS, и поэтому он квакает с неправильным номером версии .На это также указывает обычный шифр: Cipher : 0000.

Глядя на код вашего сервера, мне кажется, что вы настраиваете некоторый контекст SSL в начале (и показанный код, похоже, не работаеттоже) но на самом деле никогда не используйте его, т. е. ваш сервер только для TCP.Неудивительно, что клиент об этом кричит.

...