Запрос HTTPS в скрученном, который проверяет сертификат

В моем искривленном приложении я хочу сделать асинхронный запрос к Akismet для проверки на спам. Akismet разумно использует HTTPS, поэтому я следовал руководство веб-клиента по SSL в документации. Но вот что меня беспокоит:

Вот пример, который показывает, как использовать агент для запроса URL-адреса HTTPS без проверки сертификата.

Я очень хочу, чтобы проверка сертификата предотвращала атаки Man-In-The-Middle. Итак, как мне его добавить?

Мой тестовый код без проверки таков:

from twisted.internet import reactor
from twisted.web.client import Agent
from twisted.internet.ssl import ClientContextFactory

class WebClientContextFactory(ClientContextFactory):
    def getContext(self, hostname, port):
        print( "getting context for {}:{}".format( hostname, port ) )
        # FIXME: no attempt to verify certificates!
        return ClientContextFactory.getContext(self)

agent = Agent( reactor, WebClientContextFactory() )

def success( response ):
    print( "connected!" )
def failure( failure ):
    print( "failure: {}".format( failure ) )
def stop( ignored ):
    reactor.stop()

agent.request( "GET", "https://www.pcwebshop.co.uk/" )\ # uses self-signed cert
.addCallbacks( success, failure )\
.addBoth( stop )

reactor.run()

Я бы хотел, чтобы он потерпел неудачу из-за невозможности проверить сертификат.


person Mr. Wonko    schedule 30.04.2015    source источник


Ответы (2)


Я использую Twisted 15.1.0.

Фактически, функция инициализации по умолчанию Agent будет передаваться BrowserLikePolicyForHTTPS как contextFactory и иметь возможность проверять сертификат сервера.

Просто используя это:

agent = Agent( reactor )

выдаст следующую ошибку:

failure: [Failure instance: Traceback (failure with no frames):     
<class 'twisted.web._newclient.ResponseNeverReceived'>:
[<twisted.python.failure.Failure <class 'OpenSSL.SSL.Error'>>]]

Убедитесь, что вы установили пакет service_identity с помощью pip.


Если вам нужна настраиваемая проверка сертификата, вы можете создать настраиваемую политику, передав pem, как описано здесь:

customPolicy = BrowserLikePolicyForHTTPS(
    Certificate.loadPEM(FilePath("your-trust-root.pem").getContent())
)
agent = Agent(reactor, customPolicy)
person skyline75489    schedule 30.04.2015
comment
Сначала я так и сделал, но также получил указанную ошибку при подключении к google.com. - person Mr. Wonko; 30.04.2015
comment
Интересно, что этот ложный отрицательный результат происходит только на моем компьютере для разработки Windows. Мой сервер Ubuntu тоже успешно работает?! Я также пробовал другой веб-сайт, который определенно является самоподписанным, с тем же результатом. - person Mr. Wonko; 30.04.2015
comment
Этот BrowserLikePolicyForHTTPS будет использовать сертификаты, предоставленные системой. Может быть, поэтому результаты различаются между Ubuntu и Win. - person skyline75489; 01.05.2015
comment
Это звучит возможно, но я никогда не устанавливал сертификаты на машину с Ubuntu, и уж точно не на самоподписанные сайты. - person Mr. Wonko; 01.05.2015
comment
Это потому, что Ubuntu поставляется с установленным пакетом ca-certificates, без которого вы даже не сможете просматривать веб-сайты с действующим сертификатом, таким как SO и Github. - person skyline75489; 01.05.2015
comment
Я все еще немного беспокоюсь о сайтах, которые, как я думал, были самоподписанными, но я просто предположу, что тогда все в порядке, безопасность в любом случае не имеет решающего значения. - person Mr. Wonko; 01.05.2015

Спасибо за указание на это. Кажется, это ошибка в документации. До версии 14.0 это было точно; Twisted не проверял HTTPS, и это было большой проблемой. Однако, как видно из примечаний к выпуску для этой версии , Twisted (по крайней мере, в версиях 14.0 и выше) проверяет TLS на подключениях HTTPS, выполненных с помощью Agent. (Это по-прежнему не работает для getPage, старого, плохого HTTP-клиента; не используйте getPage.)

Я зарегистрировал эту ошибку, чтобы отследить правильность исправления документации.

person Glyph    schedule 30.04.2015