Как подключиться к серверу с помощью сертификата и ключа RSA - PullRequest
0 голосов
/ 26 апреля 2019

Я очень новичок в программировании на Python. У меня есть сертификат и ключ RAS. и я хочу написать клиентскую программу сокета Python SSL для отправки сообщения на сервер. Я знаю имя хоста сервера и порт. Я пытался ниже код.

Пожалуйста, ведите меня.

Код, который у меня пока есть:

import socket
import ssl

context = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH)
context.load_cert_chain(certfile="D:/mycerti.crt", keyfile="D:/mykey.key") 

soc = socket.socket() 
soc.bind(('xxx.xxx.xxx.xxx', 3335)) # i am giving actual ip address not xx.xx.xx. 

soc.listen(5) 

но я продолжаю получать следующую ошибку:

Traceback (most recent call last): File "\test.py", line 7, in <module> soc.bind(('xxx.xxx.xxx.xxx', 3335)) OSError: [WinError 10049] The requested address is not valid in its context

Произошла ошибка при использовании сокета openssl, и я исправил его.

context = ssl.create_default_context(ssl.Purpose.SERVER_AUTH)  # not CLIENT_AUTH
context.load_cert_chain(certfile="D:/mycerti.crt", keyfile="D:/mykey.key")

soc = socket.socket()
conn = context.wrap_socket(soc, server_hostname='your_server_hostname')  # name, not ip address

conn.connect(('xxx.xxx.xxx.xxx', 3335))

Теперь я не получаю вышеуказанную ошибку, но теперь я ошибаюсь.

Traceback (most recent call last): 
File "C:/Users/Nouman Yosuf/AppData/Local/Programs/Python/Python37-32/Test.py", line 10, in <module> conn.connect(('x.x.x.x', 3335)) 
File "C:\Users\Nouman Yosuf\AppData\Local\Programs\Python\Python37-32\lib\ssl.py", line 1150, in connect self._real_connect(addr, False) 
File "C:\Users\Nouman Yosuf\AppData\Local\Programs\Python\Python37-32\lib\ssl.py", line 1141, in _real_connect self.do_handshake() 
File "C:\Users\Nouman Yosuf\AppData\Local\Programs\Python\Python37-32\lib\ssl.py", line 1117, in do_handshake self._sslobj.do_handshake()
ssl.SSLCertVerificationError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate (_ssl.c:1056)

Я установил сертификат также как CA и как персональный. Но все же я получаю выше ошибки. Я попытался указать путь к сертификату, а также после установки сертификата тоже. Но по-прежнему не удается проверить сертификат о невозможности получить сертификат локального эмитента. Я также пытался создать контекст с нуля.

context = ssl.SSLContext()
context.verify_mode = ssl.CERT_REQUIRED
context.check_hostname = True 
context.load_verify_locations("C:/mycerti.crt") 
soc = socket.socket() 
conn = context.wrap_socket(soc, server_hostname='x.x.x.x') 
conn.connect(('x.x.x.x.', 3335)) 

Но я получаю сообщение об ошибке.

 [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: IP address mismatch, certificate is not valid for 'x.x.x.x. (_ssl.c:1056) 

И я уверен, что сертификат действителен или тот Ip.

1 Ответ

0 голосов
/ 26 апреля 2019

Вы близки, но пропускаете пару понятий.

Во-первых, если вы Клиент, вы «подключаете» свой сокет к серверу. С другой стороны, серверы «привязывают» к порту «прослушивать» входящие запросы на подключение. (Точно так же вам нужно использовать ssl.Purpose.SERVER_AUTH, а не ssl.Purpose.CLIENT_AUTH: последний используется, если вы являетесь сервером, ищущим аутентификацию клиентов) *

Во-вторых, вы создаете контекст для SSL, но вам все равно нужно связать SSLContext с самим сокетом. Для этого вы используете wrap_socket. Как у вас есть, у вас есть контекст, у вас есть сокет, но они не знают друг о друге. После этого вы используете это соединение, а не исходный соц.

Обратите внимание, что wrap_socket принимает имя сервера, а не IP-адрес. Это потому, что он проверит, чтобы убедиться, что сертификат вашего сервера совпадает с сертификатом, предоставляемым сервером (один и тот же IP может содержать много именованных серверов). Если он не совпадает, соединение не будет установлено.

Попробуйте что-то вроде этого:

import socket
import ssl

context = ssl.create_default_context(ssl.Purpose.SERVER_AUTH)  # not CLIENT_AUTH
context.load_cert_chain(certfile="D:/mycerti.crt", keyfile="D:/mykey.key")

soc = socket.socket()
conn = context.wrap_socket(soc, server_hostname='your_server_hostname')  # name, not ip address

conn.connect(('xxx.xxx.xxx.xxx', 3335))

# Connection made, so do something, like get the server's certificate
# and see when it expires...
ssl_info = conn.getpeercert()
print sl_info['notAfter']
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...