使用urllib2 / SSL?
我有一个很大的域列表,知道是否有任何我不知道的ssl证书会很有用。
答案 0 :(得分:4)
我不确定使用urllib2
。不幸的是,我能找到的最近的信息是this link和相关的代码:
import socket
import ssl
HOST = "www.google.com"
PORT = 443
# replace HOST name with IP, this should fail connection attempt
HOST = socket.getaddrinfo(HOST, PORT)[0][4][0]
print(HOST)
# create socket and connect to server
# server address is specified later in connect() method
sock = socket.socket()
sock.connect((HOST, PORT))
# wrap socket to add SSL support
sock = ssl.wrap_socket(sock,
# flag that certificate from the other side of connection is required
# and should be validated when wrapping
cert_reqs=ssl.CERT_REQUIRED,
# file with root certificates
ca_certs="cacerts.txt"
)
# security hole here - there should be an error about mismatched host name
# manual check of hostname
cert = sock.getpeercert()
for field in cert['subject']:
if field[0][0] == 'commonName':
certhost = field[0][1]
if certhost != HOST:
raise ssl.SSLError("Host name '%s' doesn't match certificate host '%s'"
% (HOST, certhost))
虽然文件中的注释相当广泛,但第一个链接中的wiki也列出了这些说明:
要验证证书是否与请求的站点匹配,您需要检查证书的
commonName
中的subject
字段。可以使用getpeercert()
包装套接字方法访问此信息。您需要
cacerts.txt
文件,其中包含与脚本一起放置的根证书 - 请参阅下文如何获取更新列表。要检查证书验证是否有效,请使用https://www.debian-administration.org/
名称中的HOST
。此站点的证书未由cacerts.txt
的任何根证书签名,因此您将收到错误消息。
您也可以查看pyopenssl module,因为根据我发布的第一个链接,它可用于以这种方式验证SSL证书:
import socket
from OpenSSL import SSL
HOST = "www.google.com"
PORT = 443
# replace HOST name with IP, this should fail connection attempt,
# but it doesn't by default
HOST = socket.getaddrinfo(HOST, PORT)[0][4][0]
print(HOST)
# uses HOST
def verify_cb(conn, x509, errno, errdepth, retcode):
"""
callback for certificate validation
should return true if verification passes and false otherwise
"""
if errno == 0:
if errdepth != 0:
# don't validate names of root certificates
return True
else:
if x509.get_subject().commonName != HOST:
return False
else:
return False
context = SSL.Context(SSL.SSLv23_METHOD)
context.set_verify(SSL.VERIFY_PEER | SSL.VERIFY_FAIL_IF_NO_PEER_CERT, verify_cb)
context.load_verify_locations("cacerts.txt")
# create socket and connect to server
sock = socket.socket()
sock = SSL.Connection(context, sock)
sock.connect((HOST, PORT))
sock.do_handshake()
根据第一个链接中的文档,对于这些示例,您将需要here中的最新证书版本。