检查证书的扭曲的 HTTPS 请求
HTTPS request in twisted that checks the certificate
在我扭曲的应用程序中,我想向 Akismet 发出异步请求以检查垃圾邮件。 Akismet 合理地使用 HTTPS,所以我一直在关注文档中的 web client guide on SSL。但是有这一部分让我担心:
Here’s an example which shows how to use Agent to request an HTTPS URL with no certificate verification.
我非常想要证书验证来防止中间人攻击。那么如何添加呢?
我未经验证的测试代码是这样的:
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()
我希望它因无法验证证书而失败。
我正在使用 Twisted 15.1.0。
实际上,Agent
的默认init函数会传入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'>>]]
确保您使用 pip 安装了 service_identity
包。
如果您需要自定义证书验证,您可以通过传入 pem 创建自定义策略,如所述here:
customPolicy = BrowserLikePolicyForHTTPS(
Certificate.loadPEM(FilePath("your-trust-root.pem").getContent())
)
agent = Agent(reactor, customPolicy)
感谢您指出这一点。这似乎是文档中的错误。在 14.0 版本之前,它是准确的; Twisted 不会验证 HTTPS,这是个大问题。但是,正如您在 the release notes for that version 中看到的那样,Twisted(至少在 14.0 及更高版本中)确实会在使用 Agent
建立的 HTTPS 连接上验证 TLS。 (对于 getPage
,旧的、坏的 HTTP 客户端,它仍然没有这样做;不要使用 getPage
。)
我已提交 this bug 以跟踪修复文档的准确性。
在我扭曲的应用程序中,我想向 Akismet 发出异步请求以检查垃圾邮件。 Akismet 合理地使用 HTTPS,所以我一直在关注文档中的 web client guide on SSL。但是有这一部分让我担心:
Here’s an example which shows how to use Agent to request an HTTPS URL with no certificate verification.
我非常想要证书验证来防止中间人攻击。那么如何添加呢?
我未经验证的测试代码是这样的:
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()
我希望它因无法验证证书而失败。
我正在使用 Twisted 15.1.0。
实际上,Agent
的默认init函数会传入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'>>]]
确保您使用 pip 安装了 service_identity
包。
如果您需要自定义证书验证,您可以通过传入 pem 创建自定义策略,如所述here:
customPolicy = BrowserLikePolicyForHTTPS(
Certificate.loadPEM(FilePath("your-trust-root.pem").getContent())
)
agent = Agent(reactor, customPolicy)
感谢您指出这一点。这似乎是文档中的错误。在 14.0 版本之前,它是准确的; Twisted 不会验证 HTTPS,这是个大问题。但是,正如您在 the release notes for that version 中看到的那样,Twisted(至少在 14.0 及更高版本中)确实会在使用 Agent
建立的 HTTPS 连接上验证 TLS。 (对于 getPage
,旧的、坏的 HTTP 客户端,它仍然没有这样做;不要使用 getPage
。)
我已提交 this bug 以跟踪修复文档的准确性。