【问题标题】:How to add OCSP support into Python requests library?如何将 OCSP 支持添加到 Python 请求库中?
【发布时间】:2014-09-12 07:57:25
【问题描述】:

有没有办法通过 requests 库实现 OCSP 检查?

我现在看到的唯一可行的方法是使用pyOpenSSL,但这意味着必须与服务器建立单独的独立连接以获取证书,然后连接到颁发者进行验证。

然后,有没有这样的实现呢? 您是否已经解决并愿意报告它?

M2Crypto 看起来也至少是 SSL 连接的候选者,但是我不确定该库可能存在的缺点,但它看起来肯定比 requests 更底层。

旁注:
显然 Python 在更复杂的 HTTP/HTTPS 连接方面真的很糟糕。

urllib 甚至不检查 SSL/TLS 证书,而 requests 带有自己的 CA 证书集合(而不是使用系统的 CA)并且似乎不支持通过 PAC 进行代理配置。

哎呀,我什至尝试使用 Qt 的 HTTP 堆栈(它使用操作系统设置),但遇到了多个并发连接的停滞问题。

【问题讨论】:

  • 您可以强制requests 使用您系统的 CA,但您必须先找到它们。您可以传入cert='/path/to/pemfile.pem' 参数来执行此操作。此外,我们的 CA 证书集合是 Mozilla 的证书库,其中删除了某些证书。还构建了夜间版本,并以certifi 分发。
  • 我已经看到 cert 选项,但据我了解,它需要一个带有 PEM 证书的文件,所以除非我运行一些使用串联的 Linux,否则这将如何与我系统的 CA 一起使用我的 CA ? Windows 没有我知道的这样的文件(Mac 也没有)。 certifi 只是另一个必须更新的集合,就像 requests 一样,尽管我想这可能更常见,因为 certifi 的唯一目的是提供证书而不是功能。
  • 如果请求是通过GEThttps://ocsp-endpoint/[BASE64_DER_REQUEST] 或以[BASE64_DER_REQUEST] 作为body 键的POST 来的,服务器是否可以?

标签: python python-3.x python-requests ocsp


【解决方案1】:

从对 pyOpenSSL 和 M2Crypto 的简短了解来看,我怀疑它们是否为 OCSP 验证提供了必要的功能,并且我看不到任何为 python 实现此类东西的认真尝试,另请参阅 http://www.gossamer-threads.com/lists/python/bugs/1092384

实施 OCSP 绝对不是一件容易的事。 OpenSSL API 未记录在案,您必须从源代码中提取必要的部分。然后,您必须尝试将它们组合在一起并从中制作出一个界面,该界面实际上可供最终用户使用。

当涉及到更复杂的 HTTP/HTTPS 连接时,显然 Python 真的很糟糕。

不仅仅是蟒蛇。如果您查看工具和编程语言,很多工具和编程语言在正确验证证书的基本任务中都失败了,那就是检查 CA,不要忘记根据给定的主机名检查证书内的名称。而且他们中的大多数要么不做 OCSP,要么只提供类似 OpenSSL 的 API,而这种 API 并不能真正以简单的方式使用。

【讨论】:

  • 是的,我也没有找到一个简单的 OCSP 接口,这就是我问的原因。太糟糕了,操作系统和各种库确实提供了无法直接利用的功能。
【解决方案2】:

实际上 OpenSSL 确实支持 OCSP。我实际上能够使用 SSL.Connection 建立一个开放的套接字,但是我的问题是在该套接字上建立一个实际的 HTTP 连接。

我不知道这是否有帮助 实际上 OpenSSL 确实支持 OCSP。我实际上能够使用 SSL.Connection 建立一个开放的套接字,但是我的问题是在该套接字上建立一个实际的 HTTP 连接。

使用以下代码,您可以打开一个 ocsp 连接并执行整个 ocsp 握手。下一步是从它创建一个 http 连接

ssl_context = Context(tls_method)
ssl_context.use_certificate_file(clientcert)
ssl_context.use_privatekey_file(clientkey)
ssl_context.load_verify_locations(cafile=None, capath=trusted_ca)
ssl_context.set_verify(VERIFY_PEER | VERIFY_FAIL_IF_NO_PEER_CERT |VERIFY_CLIENT_ONCE, callback=self.verify_callback)
ssl_context.set_ocsp_client_callback(
        callback=self.ocsp_callback, data=None)
tcp_conn = socket.create_connection((host, port))
ssl_conn = Connection(ssl_context, tcp_conn)
ssl_conn.set_tlsext_host_name(host.encode())
ssl_conn.request_ocsp()
ssl_conn.set_connect_state()
ssl_conn.do_handshake()

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-07-17
    • 1970-01-01
    • 2012-10-11
    • 2011-03-13
    • 2021-07-23
    • 1970-01-01
    • 2013-07-24
    • 1970-01-01
    相关资源
    最近更新 更多