首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >在Python中获取或构建PEM证书链

在Python中获取或构建PEM证书链
EN

Stack Overflow用户
提问于 2018-06-26 09:27:09
回答 2查看 4.4K关注 0票数 0

是否可以使用使用Python的ssl以PEM格式获取整个证书链?我可以通过以下方式得到具体的:

代码语言:javascript
运行
复制
import ssl
addr = '192.0.2.1'
cert_str = ssl.get_server_certificate((addr, 443))

给我的答案是:

代码语言:javascript
运行
复制
-----BEGIN CERTIFICATE-----
[...]
-----END CERTIFICATE-----

但我想要:

代码语言:javascript
运行
复制
-----BEGIN CERTIFICATE-----
[...]
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
[...]
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
[...]
-----END CERTIFICATE-----

我很确定这是可能的,因为我可以从我的网页浏览器下载这个。知道吗?

(我已经查过Getting certificate chain with Python 3.3 SSL module了,但我不确定这是不是我想要的.)

编辑:在Patrick回答之后我尝试了什么:

代码语言:javascript
运行
复制
from OpenSSL import SSL
import socket
dst = ('192.0.2.1', 443)
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
ctx = SSL.Context(SSL.SSLv23_METHOD)
ctx.set_alpn_protos([b'http/1.1'])
if sock.connect_ex(dst) == 0:
    connection = SSL.Connection(ctx, sock)
    cert_str = connection.get_peer_cert_chain()

但cert_str不是。我认为这是因为OpenSSL的使用遗漏了一些东西。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2018-06-26 15:06:01

如果您在Python中使用OpenSSL库,您可以在连接对象上应用get_peer_cert_chain,它将为您提供服务器发送的证书列表,因此,如果需要的话,最终证书包含所有中间服务器。

请参见https://pyopenssl.org/en/stable/api/ssl.html#connection-objects

get_peer_cert_chain() 检索对方的证书(如果有的话) 返回:提供对等方证书链的X509实例列表,如果没有证书链,则不提供证书链。

下面是一个简单的示例(没有任何错误处理):

代码语言:javascript
运行
复制
from OpenSSL import SSL
import socket

dst = ('www.google.com', 443)
ctx = SSL.Context(SSL.SSLv23_METHOD)
s = socket.create_connection(dst)
s = SSL.Connection(ctx, s)
s.set_connect_state()
s.set_tlsext_host_name(dst[0])

s.sendall('HEAD / HTTP/1.0\n\n')
s.recv(16)

certs = s.get_peer_cert_chain()
for pos, cert in enumerate(certs):
   print "Certificate #" + str(pos)
   for component in cert.get_subject().get_components():
       print "Subject %s: %s" % (component)
   print "notBefore:" + cert.get_notBefore()
   print "notAfter:" + cert.get_notAfter()
   print "version:" + str(cert.get_version())
   print "sigAlg:" + cert.get_signature_algorithm()
   print "digest:" + cert.digest('sha256')

这意味着:

代码语言:javascript
运行
复制
Certificate #0
Subject C: US
Subject ST: California
Subject L: Mountain View
Subject O: Google LLC
Subject CN: www.google.com
notBefore:20180612133452Z
notAfter:20180821121300Z
version:2
sigAlg:sha256WithRSAEncryption
digest:06:C5:12:EB:3C:B1:7F:AB:18:E0:D5:22:E4:25:12:A7:30:AA:27:16:0B:3A:99:CB:3D:11:CF:12:EF:95:2E:41
Certificate #1
Subject C: US
Subject O: Google Trust Services
Subject CN: Google Internet Authority G3
notBefore:20170615000042Z
notAfter:20211215000042Z
version:2
sigAlg:sha256WithRSAEncryption
digest:BE:0C:CD:54:D4:CE:CD:A1:BD:5E:5D:9E:CC:85:A0:4C:2C:1F:93:A5:22:0D:77:FD:E8:8F:E9:AD:08:1F:64:1B

因此,您有证书的全部详细内容,请参阅https://pyopenssl.org/en/stable/api/crypto.html#x509-objects获取可用信息。然后,您就可以使用以下内容获得to_cryptography()的PEM版本:cert.to_cryptography().public_bytes(serialization.Encoding.PEM)

但也要考虑到:

  • 最好使用回调,参见set_info_callback()方法,以便在适当的时间运行诊断信息(甚至键入SSL.SSL_CB_HANDSHAKE_DONE)。
  • 我注意到在调用get_peer_cert_chain()之前需要交换一些通信量(发送/recv)(在我的示例中,如果在sendall()之前移动它,它会返回None)。

从问题中的链接来看,当只使用ssl而不使用OpenSSL时,您似乎与ssl相当;但是,这似乎仍然被记录为带有一些可用修补程序的bug,并且可能不会发布。事实上,https://docs.python.org/3.8/library/ssl.html的最新文档并没有列出getpeercertchain()

票数 4
EN

Stack Overflow用户

发布于 2022-05-13 23:46:08

有同样的问题,很难找到一个解决方案,将PEM格式的cert链作为一个字符串输入到requests.session()中。这个函数应该返回您所要求的内容。

代码语言:javascript
运行
复制
from OpenSSL import SSL, crypto
import socket

def getPEMFile():

  dst = ('www.google.com', 443)
  ctx = SSL.Context(SSL.SSLv23_METHOD)
  s = socket.create_connection(dst)
  s = SSL.Connection(ctx, s)
  s.set_connect_state()
  s.set_tlsext_host_name(str.encode(dst[0]))

  s.sendall(str.encode('HEAD / HTTP/1.0\n\n'))

  peerCertChain = s.get_peer_cert_chain()
  pemFile = ''

  for cert in peerCertChain:
      pemFile += crypto.dump_certificate(crypto.FILETYPE_PEM, cert).decode("utf-8")

  return pemFile
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/51039393

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档