无法使用python HTTPSConnection()连接到web服务器

2024-05-15 02:23:14 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在尝试连接到使用HTTPS客户端证书身份验证的web服务器。使用curl时效果很好:

leo@leo-VirtualBox:~/development/pki-client$ curl --key admin.privkey.pem --cert admin.crt -k --url "https://ca.cloud.leotr.org/"
<!DOCTYPE html>
<html>
<head>
    <title>Welcome to CA</title>
    <link href="/static/bootstrap/css/bootstrap.min.css"  rel="stylesheet"/>
</head>
<body>

<div class="container">
    <h1>REMS CA server</h1>
    <p class="lead">Hello and welcome to REMS CA. Currently this page is
        almost empty. But you can download CA root certificate and install it
    into your browser ;)</p>
    <a class="btn btn-large btn-primary" href="/remspki/cacert/">Download CA certificate</a>
    <a class="btn btn-large" href="/admin/">Go to Admin site <i class="icon-arrow-right"></i>    </a>
</div>

</body>
</html>

客户端私钥文件内容

^{pr2}$

客户端证书

leo@leo-VirtualBox:~/development/pki-client$ cat admin.crt
-----BEGIN CERTIFICATE-----
MIIDeTCCAmGgAwIBAgIBAzANBgkqhkiG9w0BAQUFADBRMRIwEAYKCZImiZPyLGQB
GRYCS1oxGDAWBgoJkiaJk/IsZAEZFghSQUlMV0FZUzEUMBIGCgmSJomT8ixkARkW
BFJFTVMxCzAJBgNVBAMTAkNBMB4XDTEyMTIyODIyNTI1MFoXDTE3MTIyNzIyNTI1
MFowbjESMBAGCgmSJomT8ixkARkWAktaMRgwFgYKCZImiZPyLGQBGRYIUkFJTFdB
WVMxFDASBgoJkiaJk/IsZAEZFgRSRU1TMSgwEgYDVQQDEwtMZW8gVHJ1YmFjaDAS
BgoJkiaJk/IsZAEBEwRBMDAxMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC
AQEAtuyfxqDJghI9F0hyqTA2rl/RrBIL/B0oemxou0obC6xwIqdNggw/D70jEfc7
dqc5ZIsek50aDHsWeLyP/uvBWYYWh55anF9Wu1ZUHhsqS3fmJtrgEtRLyFFv3OB1
sdflGAHRajL1jADvF52n6FUl67/z6bqGfvimszD2utdBk2H3B1qoLl7aBIpbugFe
w6TiGzCUnQNGTbfxJEF9K3tLjhHN06vJg++rqmTT4Lkg4Uoi6Hn2XUUMOqi+/jFm
iXjtTIGHPRzvm1OgjC/9Yr6IEUJyhs0V5XEGHVcUTfw+YfK1DTPi/JR8dsm985c5
KPLIxWVGK0VKC67catEY5j/70wIDAQABoz8wPTAMBgNVHRMBAf8EAjAAMA4GA1Ud
DwEB/wQEAwIC/DAdBgNVHQ4EFgQUbmKGUje1HCUQVd//jZjJmgYJ2mswDQYJKoZI
hvcNAQEFBQADggEBALJEtadF5zPh6pJzj0c2vLISnZ4jBi6aaCOvz1Ph2gFrI9te
mvXVnlFLe7JJxStDlLurQ+hLqY9Q8vIczAEp2r9uJyfBpeHsc0YP6UbOXg6WLHLl
fU0tKb9PqfcMwfKUH8Nb6Q6Kt5EuQzIraYweXHNyOiKSB3ZogjPVdZnoe5gXYUpG
5cE8k2SjGVEWxc94ygcbiN+ziaUz/jos+TwqgsBp+yel0frO3DKGqQjfuOLgeTpf
xaNlPXdzFfEn0VWva36skrRzHNwZESI/Dd626eyUfxuTLLq5+Gb1D8WZj5RRqu1n
I9cZs9gCmZswWQy2/cExRPhgSWbwUWOhOCQsFVo=
-----END CERTIFICATE-----

Python代码:

leo@leo-VirtualBox:~/development/pki-client$ cat httpstest.py 
from httplib import HTTPSConnection
from config import ADMIN_CERT, ADMIN_KEY

h = HTTPSConnection(
    'ca.cloud.leotr.org', 443, key_file=ADMIN_KEY, cert_file=ADMIN_CERT)
h.request('GET', '/')
resp = h.getresponse()
print(resp.status)
print(resp.read())

输出:

leo@leo-VirtualBox:~/development/pki-client$ python httpstest.py 
400
<html>
<head><title>400 The SSL certificate error</title></head>
<body bgcolor="white">
<center><h1>400 Bad Request</h1></center>
<center>The SSL certificate error</center>
<hr><center>nginx/1.1.19</center>
</body>
</html>

让我们试试更高级的Python代码

leo@leo-VirtualBox:~/development/pki-client$ cat ssltest.py 
from config import ADMIN_CERT, ADMIN_KEY
import socket
import ssl

sock = socket.create_connection(('ca.cloud.leotr.org', 443), None)
print('Admin key: ', ADMIN_KEY)
print('Admin cert', ADMIN_CERT)
sslsock = ssl.wrap_socket(
    sock, keyfile=ADMIN_KEY, certfile=ADMIN_CERT)
request = ('GET / HTTP/1.1',
           'Host: ca.cloud.leotr.org',
           'Accept: text/html',
           'Accept-Encoding: gzip,deflate,sdch')
request_body = '\n'.join(request) + '\n'*2
sslsock.write(request_body)
response = sslsock.read()
print response

Python结果

leo@leo-VirtualBox:~/development/pki-client$ python ssltest.py
('Admin key: ', 'admin.privkey.pem')
('Admin cert', 'admin.crt')
HTTP/1.1 400 Bad Request
Server: nginx/1.1.19
Date: Fri, 04 Jan 2013 04:59:52 GMT
Content-Type: text/html
Content-Length: 231
Connection: close

<html>
<head><title>400 The SSL certificate error</title></head>
<body bgcolor="white">
<center><h1>400 Bad Request</h1></center>
<center>The SSL certificate error</center>
<hr><center>nginx/1.1.19</center>
</body>
</html>

所以我不明白怎么了。在


Tags: clientadmintitlehtmlbodycertificateh1head
1条回答
网友
1楼 · 发布于 2024-05-15 02:23:14

这里的问题是,您试图连接到不在默认CA列表中的CA。由于CA站点的证书是由CA签名的,所以在您首先下载并安装证书之前,不能通过SSL访问该站点。在

HTML结果显示有“下载CA根证书并将其安装到浏览器中”的说明。如果您不这样做,您的浏览器会显示一个错误,内容如下:

Safari can't verify the identity of the website "ca.cloud.leotr.org".

The certificate for this website is invalid. You might be connecting to a website that is pretending to be "ca.cloud.leotr.org", which could put your confidential information at risk. Would you like to connection to the website anyway?

同样,如果您尝试使用curl,则会得到相同的错误:

curl: (60) SSL certificate problem, verify that the CA cert is OK. Details: error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed More details here: http://curl.haxx.se/docs/sslcerts.html

curl performs SSL certificate verification by default, using a "bundle" of Certificate Authority (CA) public keys (CA certs). If the default bundle file isn't adequate, you can specify an alternate file using the cacert option. If this HTTPS server uses a certificate signed by a CA represented in the bundle, the certificate verification probably failed due to a problem with the certificate (it might be expired, or the name might not match the domain name in the URL). If you'd like to turn off curl's verification of the certificate, use the -k (or insecure) option.

这对curl有效的唯一原因是您指定了-k标志,即 insecure。从手册页:

-k, insecure

(SSL) This option explicitly allows curl to perform "insecure" SSL connections and transfers. All SSL connections are attempted to be made secure by using the CA certificate bundle installed by default. This makes all connections considered "insecure" fail unless -k, insecure is used.

See this online resource for further details:
http://curl.haxx.se/docs/sslcerts.html

同样,在Python代码中,也会遇到相同的错误。在

在这三种情况下,解决方案都是相同的:下载CA的证书并将其放入您的证书存储(或显式地使用它来代替默认的证书存储)。在

相关问题 更多 >

    热门问题