Python SSL 请求和 Let's Encrypt 证书

Python SSL requests and Let's Encrypt certs

我现在正在努力获得 requests library to perform a simple GET request to a site of mine with a Let's Encrypt 证书。该站点一切正常,我可以从 Chrome 访问它。 (我现在是 运行 OSX El Capitan)。

首先,我尝试向网站发出 GET 请求:

>>> import requests
>>> requests.get('https://example.com')

这给了我:

requests.exceptions.SSLError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:590)

然后我尝试了各种方法,包括获取 Let's Encrypt authority certificate,下面的 openssl 命令成功验证了我站点的证书:

> openssl s_client -CAfile ./letsencryptauthorityx1.pem -connect example.com:443

其输出包括底部的以下内容:

...
SSL-Session:
    Protocol  : TLSv1
    Cipher    : DHE-RSA-AES256-SHA
    Session-ID: ...
    Session-ID-ctx: 
    Master-Key: ...
    Key-Arg   : None
    Start Time: 1452865123
    Timeout   : 300 (sec)
    Verify return code: 0 (ok)
---

也许我在这里遗漏了一些东西,但在我看来,我的网站好像已经根据我提供的 Let's Encrypt 授权证书进行了验证。所以,我高兴地将我的 Python 代码更改为:

>>> requests.get('https://example.com', verify='./letsencryptauthorityx1.pem')

但我仍然不断收到 requests.exceptions.SSLError 错误。我也尝试过使用 DER 格式的授权证书,但后来我从 requests:

得到以下错误
requests.exceptions.SSLError: unknown error (_ssl.c:2825)

有人可以教我如何解决这个问题吗?

听起来您计算机上的 CA CERTS 不是最新的,或者 Web 服务器未配置为提供完整的证书链。

在 OSX 上,您可以将钥匙串访问中的所有证书导出到 .pem 文件,然后将请求指向该文件:http://movingpackets.net/2015/03/18/telling-openssl-about-your-root-certificates/

CA_BUNDLE = path_to_your_exported_file.pem
response = requests.get(user_account_url, verify=CA_BUNDLE)

对于在寻找此问题的 Windows 修复时偶然发现此 post 的迷失灵魂。

使用Chrome:

  1. 使用 HTTPS 打开 URL。
  2. 在地址栏上点击 "Secure"。
  3. 点击证书。
  4. 转到 "Certification Path" 选项卡。
  5. Select "Let's Encrypt Authority X3"(上一级)然后点击"View Certificate"。
  6. 转到 "Details" 选项卡并单击 "Export to File"。
  7. 在向导中单击下一步,然后 select "Base-64 encoded X.509 (.CER)",再次单击下一步。
  8. Select 文件夹和文件名(记住这个目录)。
  9. 转到该文件夹​​并右键单击证书并单击 "Install Certificate"。
  10. Select 本地计算机(需要管理员权限),单击下一步。
  11. Select "Automatically select the certificate store..."(默认),点击下一步。
  12. 单击“完成”。
  13. 运行 你的 Python 脚本。

免责声明:将 Chrome 67.0.3396.99 与 Windows 10 64 位一起使用。