如何使用python检索远程主机的TLS/SSL对等证书? [英] How can I retrieve the TLS/SSL peer certificate of a remote host using python?

查看:140
本文介绍了如何使用python检索远程主机的TLS/SSL对等证书?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要浏览IP列表,并从该IP上的证书中检索通用名称(对于每个允许端口443连接的IP).我已经能够使用套接字和ssl模块成功完成此操作.它适用于具有有效的已签名证书的所有IP,但不适用于自签名证书.

I need to scan through a list of IPs and retrieve the common name from the certificate on that IP (for every IP that allows port 443 connections). I have been able to successfully do this using the sockets and ssl modules. It works for all IPs with valid, signed certificates but it isn't working for self-signed certificates.

如果我使用此方法,则它需要由我的CA捆绑包验证的有效证书:

If I use this method, it requires a valid cert that is verified by my CA-bundle:

from socket import socket
import ssl

s = socket()
c = ssl.wrap_socket(s,cert_reqs=ssl.CERT_REQUIRED, ca_certs='ca-bundle.crt')
c.connect(('127.0.0.1', 443))

print c.getpeercert()

如果我删除了cert_reqs=ssl.CERT_REQUIRED,则它会连接,但根本无法获得证书.

If I remove the cert_reqs=ssl.CERT_REQUIRED then it connects but doesn't get the certificate at all.

无论证书是否通过ca-bundle进行验证,如何获取IP上证书的通用名称?

How can I retrieve the common name for a certificate on an IP whether it validates against the ca-bundle or not?

推荐答案

python ssl库似乎仅在具有有效签名的情况下才为您解析证书.

The python ssl library seems like it only parses out the cert for you if it has a valid signature.

    """Returns a formatted version of the data in the
    certificate provided by the other end of the SSL channel.
    Return None if no certificate was provided, {} if a
    certificate was provided, but not validated."""

您仍然可以使用ssl.get_server_certificate()函数获取服务器证书,但是它将以PEM格式返回. (或者,您可以调用c.getpeercert(True),它以二进制DER格式返回证书,无论该证书是否经过验证.)

You can still get the server certificate with the ssl.get_server_certificate() function, but it returns it in PEM format. (Alternatively, you could call c.getpeercert(True), which returns the cert in binary DER format, whether it's validated or not.)

>>> print ssl.get_server_certificate(('server.test.com', 443))
-----BEGIN CERTIFICATE-----
MIID4zCCAsugAwIBA.....

在这里,我将使用M2Crypto或OpenSSL来读取证书并获取值:

From here, I would use M2Crypto or OpenSSL to read the cert and get values:

# M2Crypto
cert = ssl.get_server_certificate(('www.google.com', 443))
x509 = M2Crypto.X509.load_cert_string(cert)
x509.get_subject().as_text()
# 'C=US, ST=California, L=Mountain View, O=Google Inc, CN=www.google.com'

# OpenSSL
x509 = OpenSSL.crypto.load_certificate(OpenSSL.crypto.FILETYPE_PEM, cert)
x509.get_subject().get_components()
#[('C', 'US'),
# ('ST', 'California'),
# ('L', 'Mountain View'),
# ('O', 'Google Inc'),
# ('CN', 'www.google.com')]

这篇关于如何使用python检索远程主机的TLS/SSL对等证书?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆