Python Requests SSL错误(证书验证失败)

4
我已经为我的服务器和客户端生成了以下自签名证书。
我创建了ca.crt和ca.key。使用ca.crt和ca.key,我分别为服务器创建了server.crt和server.key,为客户端创建了client.crt和client.key。
我正在使用Python请求库作为客户端。以下是代码片段:
import json
import requests

cert = ("/home/tests/certs/client.crt",
        "/home/tests/certs/client.key")


class TestCart():

    def test_cart(self, **kwargs):
        url = "https://192.168.X.Y/cart"
        cart_data = {
            'id': kwargs.get('id'),
            'items': kwargs.get('items')
        }
        req_data = json.dumps(cart_data)
        resp = requests.post(url,
                             data=req_data,
                             verify="/home/certs/ca.cert",
                             cert=cert)
        print resp.text


if __name__ == '__main__':
    t_cart = TestCart()
    data = {'id': 'ba396e79-0f0f-4952-a931-5a528c9ff72c', 'items': []}
    t_cart.test_cart(**data)

这会引发异常:
requests.exceptions.SSLError: HTTPSConnectionPool(host='192.168.X.Y', 
port=443): Max retries exceeded with url: /cart (Caused by 
SSLError(SSLError(1, u'[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify 
failed (_ssl.c:590)'),))

如果我使用verify=False,代码可以运行,但是我想要验证。在我的请求中,verify应该是什么值?

1个回答

2

强烈建议深入阅读requests的优秀文档。它有一个特别的章节SSL证书验证,其中解释了:

You can pass verify the path to a CA_BUNDLE file or directory with certificates of trusted CAs:

>>> requests.get('https://github.com', verify='/path/to/certfile')
假设您的服务器证书由您的 ca.crt 签名,则应将其用于 verify 参数。
编辑:根据讨论,看起来 CA 和服务器证书使用了相同的主题。这意味着证书验证假定这是一个自签名证书,从而导致证书验证错误。

它仍然抛出异常:(由于 SSLError(SSLError(1,u'[SSL:CERTIFICATE_VERIFY_FAILED]证书验证失败(_ssl.c:590)'))引起)。 - nebi
@nebi:目前不清楚您的代码具体内容以及证书的内容。但是,问题可能就隐藏在这个未知的部分中。如果您能够发布一个最小化、完整化和可验证的示例,那么这将会非常有帮助。 - Steffen Ullrich
@nebi:目前代码看起来不错,但仍不清楚您使用的 ca.crt 与服务器发送的证书有何关系。如果此文件不包含颁发服务器证书的 CA,或者在 CA 和服务器证书之间存在中间 CA,这些中间 CA 既未由服务器提供,也未包含在 ca.crt 中,则验证仍将失败。此外,证书的主题应与 URL 的主机名匹配。 - Steffen Ullrich
我已经按照以下方式生成了证书:“openssl req -new -key ca.key -x509 -days 365 -out ca.crt”和“openssl x509 -req -days 365 -in server.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out server.crt”。我需要提供所有的命令吗? - nebi
@nebi:如果您提供这些命令生成的实际示例证书,那么人们就可以使用它们来重现问题。因为相同的命令可能会根据配置和OpenSSL版本而产生不同的证书,所以这样做可能会更好。 - Steffen Ullrich
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接