python - 在 Python 中使用带有自签名证书的请求时证书验证失败

标签 python ssl https python-requests ssl-certificate

我正在使用 python 通过 API 访问 Aruba 交换机。我想使用 HTTPS 来加密我的流量(即发送用户名和密码进行验证):

import requests
import json
import base64
from requests.packages.urllib3.exceptions import InsecureRequestWarning
requests.packages.urllib3.disable_warnings(InsecureRequestWarning)
import certifi

url = 'https://10.4.10.10/rest/v3/'
creds = {'userName': 'username', 'password': 'password'}
command = 'show config'

s = requests.Session()
r = s.post(url + 'login-sessions', data=json.dumps(creds), timeout=1)
print(r.json())
cookie_response = r.json()['cookie']
if r.status_code != 201:
    print('Login error, status code {}'.format(r.status_code))

我在 CLI 中生成了一个自签名证书,然后可以通过将 IP 地址放入 chrome 中(前面带有 https://)来获取它,然后下载证书文件。我必须使用 openssl 将证书文件类型转换为 .pem。最后,我在文本编辑器中打开该文件,并将证书添加到 Requests 模块使用的 cacert.pem 文件的末尾。完成所有这些后,我仍然收到以下错误:

ssl.SSLCertVerificationError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate (_ssl.c:1076)

我查遍了,还是没有找到解决办法。任何帮助或想法将不胜感激!谢谢!

-编辑-

这是我正在使用的证书的内容:

Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number:
            17:13:91:1c:86:72:ae:bd:01:27:28:39:8f:4e:5a:2d:18:ae:1f:04
        Signature Algorithm: sha256WithRSAEncryption
        Issuer: CN=testSwitch, OU=OCSwitch, O=OC, L=Edmond, ST=Oklahoma, C=US
        Validity
            Not Before: Jun 16 10:59:12 2020 GMT
            Not After : Jun 16 23:59:59 2021 GMT
        Subject: CN=testSwitch, OU=OCSwitch, O=OC, L=Edmond, ST=Oklahoma, C=US
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
            RSA Public Key: (1024 bit)
                Modulus (1024 bit):
                    00:be:6a:27:02:f5:6a:98:19:0f:db:c7:11:26:dd:
                    77:26:bd:18:ef:ab:62:53:3e:13:a1:61:b0:5a:88:
                    77:d8:ba:81:56:2a:7d:66:0a:2c:cd:f1:78:4b:35:
                    61:73:31:4c:4f:80:51:21:86:bf:2c:1c:95:87:cc:
                    e7:5f:47:d8:d8:6e:ed:d4:4f:56:79:24:01:65:c9:
                    72:cb:6c:7a:55:ef:9b:1b:ae:4e:28:8f:27:50:1d:
                    36:08:c3:85:67:2c:8a:1a:42:15:83:d2:e3:b3:ef:
                    d3:ce:cd:77:d5:3f:25:f5:b3:c1:ce:e8:7c:e1:cb:
                    fc:c5:12:e8:0a:d0:87:1b:4d
                Exponent: 65537 (0x10001)
        X509v3 extensions:
            X509v3 Key Usage: critical
                Digital Signature, Key Encipherment, Key Agreement
            X509v3 Extended Key Usage: 
                TLS Web Server Authentication
    Signature Algorithm: sha256WithRSAEncryption
        51:01:6c:13:40:8a:73:70:96:71:ea:b1:4b:b1:36:c3:82:ed:
        2b:3a:d8:b3:23:77:6e:bb:56:d5:71:56:ff:0a:66:4f:81:69:
        ef:33:9e:1f:ff:20:3e:49:70:c4:8b:c9:92:65:ce:80:78:62:
        0e:e4:8e:39:ee:e0:04:6d:73:67:41:1a:dd:1e:ec:19:af:45:
        0b:f3:4b:2e:88:10:5e:c1:89:6b:37:d1:12:a7:23:e1:86:94:
        4f:b2:8a:fd:62:d6:33:5f:14:62:50:2e:38:0f:b1:46:55:ad:
        46:71:df:b3:6d:44:48:c9:72:f5:0b:0a:13:ed:9a:2f:05:5c:
        05:0b

我通过导入 ssl 并使用 ssl.get_server_certificate() 修改了我的代码:

import ssl

cert = ssl.get_server_certificate(('10.4.10.10', 443))
with open('cert.pem', 'w') as file:
    file.write(cert)

然后我用 verify= 指向“cert.pem”,但仍然收到相同的错误。

最佳答案

    X509v3 extensions:
        X509v3 Key Usage: critical
            Digital Signature, Key Encipherment, Key Agreement
        X509v3 Extended Key Usage: 
            TLS Web Server Authentication

这是叶证书而不是 CA 证书(没有基本约束 CA:true)。不过,OpenSSL 历来要求用于验证的信任 anchor 是自签名 CA 证书。

仅当选项 X509_V_FLAG_PARTIAL_CHAIN 时,此设置才会在较新版本(OpenSSL 1.0.2 及更高版本)中更改。用于证书验证。在这种情况下,CA 存储中的任意 CA 证书都可以作为信任 anchor ,并且没有 CA:true 的自签名证书似乎也可以工作。

不幸的是,这个标志尚未在 Python 中公开,我看不到如何指定自定义验证选项或具有特殊验证选项的自定义上下文 requests 。对于其他库,这可能更可行,请参阅 Python WWS Library requires entire certificate chain to verify server .

关于python - 在 Python 中使用带有自签名证书的请求时证书验证失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62416452/

相关文章:

apache - 如何为 httpd 服务器的 www 和非 www 域编写 SSL 虚拟主机?

javascript - 带有 wss ://的 WebSocket 操作码 7

php - HTTPS 返回包含 header 的纯文本

python - rijndael:在 C 和 Python 中加密/解密相同的数据

python - 通过 Websockets 在 Nodejs 和 Python 之间通信

python - 在 Keras Tensorflow 中将 TimeseriesGenerator 与多元数据集结合使用

apache - 除了特定页面之外,如何将 http 重定向到 https,然后将 https 重定向到同一页面的 http?

python - 使用带有时间序列数据的 pandas 数据框作为 SciPy 优化的基础

html - 无法自动将 Ionos 微软托管网站重定向到 https

ssl - 如何在 Erlang/YAWS 中启用 ssl/crypto