Клиент Python - SSL lib - проверка сертификата не удалась - PullRequest
11 голосов
/ 21 сентября 2011

Я пытаюсь создать небольшой защищенный HTTPS-клиент для обучения и посмотреть, как работает вся механика SSL на более высоком уровне, поэтому я пытаюсь преобразовать простой сокет в ssl через ssl.wrap_socket..

Возможно, я получил всю концепцию задом наперед, но вот что я делаю:

s.connect((host, port))
if port == 443:
    f = open('cacerts.txt', 'r')
    calist = f.read()
    f.close()
    ca = ssl.get_server_certificate((host, port), ssl_version=ssl.PROTOCOL_SSLv3|ssl.PROTOCOL_TLSv1)
    if not ca in calist:
        f = open('cacerts.txt', 'a')
        f.write(ca)
        f.close()
    s = ssl.wrap_socket(s, ssl_version=ssl.PROTOCOL_SSLv3|ssl.PROTOCOL_TLSv1, cert_reqs=ssl.CERT_REQUIRED, ca_certs="cacerts.txt")
    s.do_handshake()

И когда я вызываю do_handshake (), я получаю это:

Traceback (most recent call last):
  File "SSL_test.py", line 84, in Requester
    s = ssl.wrap_socket(s, ssl_version=ssl.PROTOCOL_SSLv3|ssl.PROTOCOL_TLSv1, cert_reqs=ssl.CERT_REQUIRED, ca_certs="cacerts.txt")
  File "C:\Python26\lib\ssl.py", line 338, in wrap_socket
    suppress_ragged_eofs=suppress_ragged_eofs)
  File "C:\Python26\lib\ssl.py", line 120, in __init__
    self.do_handshake()
  File "C:\Python26\lib\ssl.py", line 279, in do_handshake
    self._sslobj.do_handshake()
ssl.SSLError: [Errno 1] _ssl.c:490: error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed

Я некоторое время искал и пытался найти что-то, что было бы близко к тому, что я делаю, но все указывают либо на PyOpenSSL, либо на Twisted, и я бы предпочел, чтобы я мог остаться вне этих библиотек, главным образом потому, что позжеЯ планирую перенести это в сложную производственную среду, где мне разрешено использовать только встроенные библиотеки Python2.6.

Любая помощь будет очень полезна!

Ответы [ 2 ]

9 голосов
/ 21 сентября 2011

Проблема здесь в том, что вы не можете проверить сертификат с самим собой (это то, что вы пытаетесь сделать), если он не самоподписан и не установлен бит CA.Вы должны добавить настоящий сертификат CA веб-сайта в файл cacerts.txt.Другая альтернатива (что-то вроде «все равно подключиться» в веб-браузере) - сбросить cert_reqs до ssl.CERT_NONE после того, как вы получите такое исключение, и понять, что в середине может быть человек.Проблема не в модуле ssl, а в том, как работает SSL / X.509.

1 голос
/ 03 декабря 2013

Если вы только учитесь, вы также можете использовать Anonymous Diffie-Hellman , то есть сервер вообще не имеет сертификата, и ваш клиент не хочет его проверять.

Ниже приведен простой (и небезопасный) тест.

Тестовый сервер, предоставлен пакет openssl:

openssl s_server  -nocert -cipher "ALL:aNULL:eNULL"

Тестовый клиент в Python:

...
ssl.wrap_socket(..., ciphers="ALL:aNULL:eNULL")
...

-

Еслиесли вы хотите играть с сертификатами, пакет openssl может генерировать то, что вы хотите, но это немного сложно сделать правильно.Хороший инструмент с графическим интерфейсом - TinyCA, он написан на perl и использует команды openssl, но предлагает вам подходящую среду для создания собственных ЦС, подписи собственных сертификатов и т. Д.

Если вы спешите, просто установитеapache, запустите его, ваш дистрибутив (linux или wamp), скорее всего, создаст самозаверяющий сертификат, чтобы начать работу.Настройте apache так, чтобы вы могли подключиться к https://localhost с помощью браузера.Затем используйте этот сервер для подключения, я думаю, у вас все получится, если вы добавите самозаверяющий CA-сервер в список / файл CA ваших клиентов.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...