Python客户端证书请求在Ubuntu上失败

时间:2019-06-03 15:13:04

标签: python-requests client-certificates

我有以下最小文件:

import requests
index_response = requests.get("https://my.end.point.com/", cert="mypem.pem")
print(index_response.status_code)
  • Windows Python 2.7.15 (v2.7.15:ca079a3ea3, Apr 30 2018, 16:30:26) [MSC v.1500 64 bit (AMD64)] on win32的响应为200
  • Ubuntu Python 2.7.15 (default, Jun 3 2019, 14:08:52) [GCC 4.8.4] on linux2的响应为403

两者都使用Python 2.7.15,并且没有显示任何错误,因此我不清楚从哪里开始寻找。我知道这不是一个容易复制的示例;如果有任何我可以使用的PEM /端点示例,我很乐意编辑我的问题。

1 个答案:

答案 0 :(得分:1)

首先,如@ wowkin2所述,确保在两台计算机上使用相同版本的请求和urllib3。我在这里使用request == 2.22.0和urllib3 == 1.25.7。

并且请考虑切换到Python 3,Python 2支持将于2020年1月结束。

好,因此,如果您使用相同的版本,但仍然看到此问题,让我们尝试首先使用另一个客户端证书来对其进行调试。 badssl.com是提供此类客户端证书的TLS测试服务。使用badssl.com进行的测试比原本要复杂的多,因为它使用了密码,并且请求不支持现成的密码,但是您可以按照以下方式进行操作:

import requests
from requests.adapters import HTTPAdapter
from urllib3.poolmanager import PoolManager


class ClientCertPasswordAdapter(HTTPAdapter):
    def __init__(self, password):
        self.password = password
        super(ClientCertPasswordAdapter, self).__init__()

    def init_poolmanager(self, connections, maxsize, block=False):
        self.poolmanager = PoolManager(
            num_pools=connections,
            maxsize=maxsize,
            block=block,
            key_password=self.password,
        )


print("fetching client certificate")
with open("client.pem", "wb") as f:
    r = requests.get("https://badssl.com/certs/badssl.com-client.pem")
    f.write(r.content)

print("requesting data")
s = requests.Session()
s.mount("https://client.badssl.com/", ClientCertPasswordAdapter("badssl.com"))
r = s.get("https://client.badssl.com/", cert="client.pem")
print(r.status_code)

此打印200是否适用于您的两个OS?这样可以排除证书中的问题。

您可以进行的另一项测试是使用客户端证书,并将其提供给不会验证该证书但会打印收到的公共信息的服务器。我在这里发送badssl.com客户证书:

import requests
from requests.adapters import HTTPAdapter
from urllib3.poolmanager import PoolManager


class ClientCertPasswordAdapter(HTTPAdapter):
    def __init__(self, password):
        self.password = password
        super(ClientCertPasswordAdapter, self).__init__()

    def init_poolmanager(self, connections, maxsize, block=False):
        self.poolmanager = PoolManager(
            num_pools=connections,
            maxsize=maxsize,
            block=block,
            key_password=self.password,
        )


print("fetching client certificate")
with open("client.pem", "wb") as f:
    r = requests.get("https://badssl.com/certs/badssl.com-client.pem")
    f.write(r.content)

print("requesting data")
s = requests.Session()
s.mount("https://server.cryptomix.com/", ClientCertPasswordAdapter("badssl.com"))
r = s.get("https://server.cryptomix.com/secure/", cert="client.pem")
print(r.status_code)
print(r.text)

这应该打印调试信息,包括SSL_CLIENT信息:

[SSL_CLIENT_S_DN_C] => US
[SSL_CLIENT_S_DN_ST] => California
[SSL_CLIENT_S_DN_L] => San Francisco
[SSL_CLIENT_S_DN_O] => BadSSL
[SSL_CLIENT_S_DN_CN] => BadSSL Client Certificate
[SSL_CLIENT_I_DN_C] => US
[SSL_CLIENT_I_DN_ST] => California
[SSL_CLIENT_I_DN_L] => San Francisco
[SSL_CLIENT_I_DN_O] => BadSSL
[SSL_CLIENT_I_DN_CN] => BadSSL Client Root Certificate Authority
[SSL_CLIENT_VERIFY] => GENEROUS
[SSL_CLIENT_M_VERSION] => 3
[SSL_CLIENT_M_SERIAL] => 2B936CE32D82CE8B01FD9A0595AC6366AA014C82
[SSL_CLIENT_V_START] => Nov 27 00:19:57 2019 GMT
[SSL_CLIENT_V_END] => Nov 26 00:19:57 2021 GMT
[SSL_CLIENT_V_REMAIN] => 730
[SSL_CLIENT_S_DN] => CN=BadSSL Client Certificate,O=BadSSL,L=San Francisco,ST=California,C=US
[SSL_CLIENT_I_DN] => CN=BadSSL Client Root Certificate Authority,O=BadSSL,L=San Francisco,ST=California,C=US
[SSL_CLIENT_A_KEY] => rsaEncryption
[SSL_CLIENT_A_SIG] => sha256WithRSAEncryption
[SSL_CLIENT_CERT_RFC4523_CEA] => { serialNumber 248774298121081469895139733087446207053965642882, issuer rdnSequence:"CN=BadSSL Client Root Certificate Authority,O=BadSSL,L=San Francisco,ST=California,C=US" }

在两个操作系统上您看到相同的值吗?