我是Windows用户。我使用Python 3.6.5
并导入了此版本的OpenSSL OpenSSL 1.0.2k
。
我需要为python TLS客户端编写一个脚本,该脚本可以根据受支持的TLS版本和密码套件以及其他配置进行自定义。客户端应该能够使用自签名证书建立连接。因此,我相信我应该使用:ssl.SSLContext()
创建上下文而不是ssl.create_default_context()
。
但是,使用以下脚本,我将永远无法获得对等方的证书。请提供清晰的代码答案,否则我将尝试许多解决方案,并且毫无希望地看了以前的帖子。
context = ssl.SSLContext() # ssl.create_default_context()
#context.verify_mode = ssl.CERT_NONE
#context.check_hostname = True
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
domain="google.com"
ssl_sock = context.wrap_socket(s, server_hostname=domain)
ssl_sock.connect((domain, 443))
print("====== peer's certificate ======")
try:
cert = ssl_sock.getpeercert()
print ("issued to:", dict(itertools.chain(*cert["subject"]))["commonName"])
print ("issued by:", dict(itertools.chain(*cert["issuer"]))["commonName"])
print("issuance date:", cert["notBefore"])
print("expairy date: ", cert["notAfter"])
if (cert == None):
print("no certificate")
except Exception as e:
print("Error:",e)
ssl_sock.close()
问题是我使用ssl.SSLContext()
时没有收到对等方的证书,但是使用时ssl.create_default_context()
正确接收了它。但是,我必须能够接收自签名证书(即未验证的证书),这就是我必须使用的原因ssl.SSLContext()
。
感谢您发布解决方案。但是我需要解析证书,即使它未经验证(自签名)。我信任此证书,并且需要其信息。我看了几篇帖子,包括这篇。我做了这些步骤:
.pem
服务器证书的内容。C:\Python36\Lib\site-packages\certifi
cacert.pem
放置在目录中的文件(第2步)-----BEGIN CERTIFICATE-----
以-----END CERTIFICATE-----
我收到此错误:
ssl.SSLError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:833)
这是一个9行代码段,可从任何URL抓取证书数据。
import ssl
import socket
def getcertmeta(url="",port=443):
hostname = socket.gethostbyaddr(url)[0]
context = ssl.create_default_context()
with socket.create_connection((hostname, port)) as sock:
with context.wrap_socket(sock, server_hostname=hostname) as ssock:
return ssock.context.get_ca_certs()
锡箔纸注意:这种可证明的东西正在变得有些腥。它们是各种问题的根源,但科技公司却痴迷于它们。它们没有提供安全性好处,每个证书颁发机构都被黑了(LetsEncrypt iirc除外),这是无可辩驳的,可以在idk 5分钟内在线查找和发现,还有其他事情发生,但是它们是如此复杂且不必要地复杂,以至于很难弄清楚是什么。我将它们与intel ME一起用于将服务器数据后门到中央位置(例如wileaks v7揭示的黑客攻击),我手机上的证书包括3-4个政府,只是直截了当地说日本政府或中国政府,并且一堆像“星光技术”这样的英特尔代理公司,它们都是非常可疑的imo。
EDIT2:上面的代码段是错误的,它只获取证书颁发机构certs而不是实际的URL,这是一个13行的代码段,用于获取实际URL的证书。
import socket,ssl
from contextlib import contextmanager
@contextmanager
def fetch_certificate(url="", port=443, timeout=0.5):
cxt = ssl.create_default_context()
sslctxsock = cxt.wrap_socket(socket.socket(), server_hostname=hostname)
sslctxsock.settimeout(timeout)
sslctxsock.connect((url,port))
cert = sslctxsock.getpeercert()
try:
yield cert
finally:
sslctxsock.close()
像这样使用它:
with fetch_certificate(url=url) as cert:
print(cert)
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句