Getting certificate chain with Python 3.3 SSL module(使用 Python 3.3 SSL 模块获取证书链)
问题描述
我可以通过 SSL 套接字上的 getpeercert() 方法获取 Python 3.3 中 SSL 连接的标准证书信息.但是,它似乎没有像 OpenSSL 的s_client"工具那样提供链.
I can get the standard certificate information for an SSL connection in Python 3.3 via the getpeercert() method on the SSL socket. However, it doesn't seem to provide the chain like OpenSSL's "s_client" tool does.
有什么方法可以让我看到我的 IA 证书是否配置正确?
Is there some way I can get this so that I can see if my IA certificate was configured properly?
s_client 命令行:
s_client command-line:
openssl s_client -connect google.com:443
s_client 结果(仅前几行):
s_client result (just the first few lines):
$ openssl s_client -connect google.com:443
CONNECTED(00000003)
depth=2 C = US, O = GeoTrust Inc., CN = GeoTrust Global CA
verify error:num=20:unable to get local issuer certificate
verify return:0
---
Certificate chain
0 s:/C=US/ST=California/L=Mountain View/O=Google Inc/CN=*.google.com
i:/C=US/O=Google Inc/CN=Google Internet Authority G2
1 s:/C=US/O=Google Inc/CN=Google Internet Authority G2
i:/C=US/O=GeoTrust Inc./CN=GeoTrust Global CA
2 s:/C=US/O=GeoTrust Inc./CN=GeoTrust Global CA
i:/C=US/O=Equifax/OU=Equifax Secure Certificate Authority
---
Python 3.3 代码:
Python 3.3 code:
import socket
from ssl import SSLContext # Modern SSL?
from ssl import HAS_SNI # Has SNI?
from pprint import pprint
def ssl_wrap_socket(sock, keyfile=None, certfile=None, cert_reqs=None,
ca_certs=None, server_hostname=None,
ssl_version=None):
context = SSLContext(ssl_version)
context.verify_mode = cert_reqs
if ca_certs:
try:
context.load_verify_locations(ca_certs)
# Py32 raises IOError
# Py33 raises FileNotFoundError
except Exception as e: # Reraise as SSLError
raise ssl.SSLError(e)
if certfile:
# FIXME: This block needs a test.
context.load_cert_chain(certfile, keyfile)
if HAS_SNI: # Platform-specific: OpenSSL with enabled SNI
return context.wrap_socket(sock, server_hostname=server_hostname)
return context.wrap_socket(sock)
hostname = 'www.google.com'
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((hostname, 443))
sslSocket = ssl_wrap_socket(s,
ssl_version=2,
cert_reqs=2,
ca_certs='/usr/local/lib/python3.3/dist-packages/requests/cacert.pem',
server_hostname=hostname)
pprint(sslSocket.getpeercert())
s.close()
代码结果:
{'issuer': ((('countryName', 'US'),),
(('organizationName', 'Google Inc'),),
(('commonName', 'Google Internet Authority G2'),)),
'notAfter': 'Sep 25 15:09:31 2014 GMT',
'notBefore': 'Sep 25 15:09:31 2013 GMT',
'serialNumber': '13A87ADB3E733D3B',
'subject': ((('countryName', 'US'),),
(('stateOrProvinceName', 'California'),),
(('localityName', 'Mountain View'),),
(('organizationName', 'Google Inc'),),
(('commonName', 'www.google.com'),)),
'subjectAltName': (('DNS', 'www.google.com'),),
'version': 3}
推荐答案
感谢 Aleksi 的贡献答案,我发现了一个错误/功能请求已经请求了这个东西:http://bugs.python.org/issue18233.尽管更改尚未最终确定,但他们确实有一个补丁可以使此功能可用:
Thanks to the contributing answer by Aleksi, I found a bug/feature request that already requested this very thing: http://bugs.python.org/issue18233. Though the changes haven't been finalized, yet, they do have a patch that makes this available:
这是我从某个被遗忘的来源窃取并重新组装的测试代码:
This is the test code which I've stolen from some forgotten source and reassembled:
import socket
from ssl import wrap_socket, CERT_NONE, PROTOCOL_SSLv23
from ssl import SSLContext # Modern SSL?
from ssl import HAS_SNI # Has SNI?
from pprint import pprint
def ssl_wrap_socket(sock, keyfile=None, certfile=None, cert_reqs=None,
ca_certs=None, server_hostname=None,
ssl_version=None):
context = SSLContext(ssl_version)
context.verify_mode = cert_reqs
if ca_certs:
try:
context.load_verify_locations(ca_certs)
# Py32 raises IOError
# Py33 raises FileNotFoundError
except Exception as e: # Reraise as SSLError
raise SSLError(e)
if certfile:
# FIXME: This block needs a test.
context.load_cert_chain(certfile, keyfile)
if HAS_SNI: # Platform-specific: OpenSSL with enabled SNI
return (context, context.wrap_socket(sock, server_hostname=server_hostname))
return (context, context.wrap_socket(sock))
hostname = 'www.google.com'
print("Hostname: %s" % (hostname))
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((hostname, 443))
(context, ssl_socket) = ssl_wrap_socket(s,
ssl_version=2,
cert_reqs=2,
ca_certs='/usr/local/lib/python3.3/dist-packages/requests/cacert.pem',
server_hostname=hostname)
pprint(ssl_socket.getpeercertchain())
s.close()
输出:
Hostname: www.google.com
({'issuer': ((('countryName', 'US'),),
(('organizationName', 'Google Inc'),),
(('commonName', 'Google Internet Authority G2'),)),
'notAfter': 'Sep 11 11:04:38 2014 GMT',
'notBefore': 'Sep 11 11:04:38 2013 GMT',
'serialNumber': '50C71E48BCC50676',
'subject': ((('countryName', 'US'),),
(('stateOrProvinceName', 'California'),),
(('localityName', 'Mountain View'),),
(('organizationName', 'Google Inc'),),
(('commonName', 'www.google.com'),)),
'subjectAltName': (('DNS', 'www.google.com'),),
'version': 3},
{'issuer': ((('countryName', 'US'),),
(('organizationName', 'GeoTrust Inc.'),),
(('commonName', 'GeoTrust Global CA'),)),
'notAfter': 'Apr 4 15:15:55 2015 GMT',
'notBefore': 'Apr 5 15:15:55 2013 GMT',
'serialNumber': '023A69',
'subject': ((('countryName', 'US'),),
(('organizationName', 'Google Inc'),),
(('commonName', 'Google Internet Authority G2'),)),
'version': 3},
{'issuer': ((('countryName', 'US'),),
(('organizationName', 'Equifax'),),
(('organizationalUnitName',
'Equifax Secure Certificate Authority'),)),
'notAfter': 'Aug 21 04:00:00 2018 GMT',
'notBefore': 'May 21 04:00:00 2002 GMT',
'serialNumber': '12BBE6',
'subject': ((('countryName', 'US'),),
(('organizationName', 'GeoTrust Inc.'),),
(('commonName', 'GeoTrust Global CA'),)),
'version': 3},
{'issuer': ((('countryName', 'US'),),
(('organizationName', 'Equifax'),),
(('organizationalUnitName',
'Equifax Secure Certificate Authority'),)),
'notAfter': 'Aug 22 16:41:51 2018 GMT',
'notBefore': 'Aug 22 16:41:51 1998 GMT',
'serialNumber': '35DEF4CF',
'subject': ((('countryName', 'US'),),
(('organizationName', 'Equifax'),),
(('organizationalUnitName',
'Equifax Secure Certificate Authority'),)),
'version': 3})
这篇关于使用 Python 3.3 SSL 模块获取证书链的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:使用 Python 3.3 SSL 模块获取证书链
基础教程推荐
- Plotly:如何设置绘图图形的样式,使其不显示缺失日期的间隙? 2022-01-01
- 求两个直方图的卷积 2022-01-01
- 修改列表中的数据帧不起作用 2022-01-01
- PANDA VALUE_COUNTS包含GROUP BY之前的所有值 2022-01-01
- 包装空间模型 2022-01-01
- 使用大型矩阵时禁止 Pycharm 输出中的自动换行符 2022-01-01
- 在Python中从Azure BLOB存储中读取文件 2022-01-01
- 无法导入 Pytorch [WinError 126] 找不到指定的模块 2022-01-01
- 在同一图形上绘制Bokeh的烛台和音量条 2022-01-01
- PermissionError: pip 从 8.1.1 升级到 8.1.2 2022-01-01
