如何在python中获取证书颁发者信息?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/30862099/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-19 09:06:12  来源:igfitidea点击:

How can i get Certificate issuer information in python?

pythonsslcertificatessl-certificate

提问by Raj

I want the 'issued to' information from certificate in python. I try to use the SSL and SSLSocket library but did not happen.

我想要来自 python 证书的“颁发给”信息。我尝试使用 SSL 和 SSLSocket 库,但没有发生。

enter image description here

在此处输入图片说明

采纳答案by mhawke

Updated answer

更新答案

If you can establish a connection to the remote server you can use the sslstandard library module:

如果可以建立到远程服务器的连接,则可以使用ssl标准库模块:

import ssl, socket

hostname = 'google.com'
ctx = ssl.create_default_context()
with ctx.wrap_socket(socket.socket(), server_hostname=hostname) as s:
    s.connect((hostname, 443))
    cert = s.getpeercert()

subject = dict(x[0] for x in cert['subject'])
issued_to = subject['commonName']
issuer = dict(x[0] for x in cert['issuer'])
issued_by = issuer['commonName']

>>> issued_to
u'*.google.com'
>>> issued_by
u'Google Internet Authority G2'

Original answer

原答案

Use pyOpenSSL.

使用pyOpenSSL

from OpenSSL import crypto

cert_file = '/path/to/your/certificate'
cert = crypto.load_certificate(crypto.FILETYPE_PEM, open(cert_file).read())
subject = cert.get_subject()
issued_to = subject.CN    # the Common Name field
issuer = cert.get_issuer()
issued_by = issuer.CN

You can also access additional components, e.g. organisation (subject.O/issuer.O), organisational unit (subject.OU/issuer.OU).

您还可以访问其他组件,例如组织 ( subject.O/ issuer.O)、组织单位 ( subject.OU/ issuer.OU)。

Your certificate file might be in another format, so you could try crypto.FILETYPE_ASN1instead of crypto.FILETYPE_PEM.

您的证书文件可能是另一种格式,因此您可以尝试crypto.FILETYPE_ASN1代替crypto.FILETYPE_PEM.

回答by Tarun Venugopal Nair

import os
import re
os.system('keytool -printcert -sslserver google.com:443 >cert.txt')
fh = open("cert.txt", "r")
content = fh.readlines()
fh.close()
content = content[2]
m = re.search('CN=(.+?),', content)
if m:
    found = m.group(1)
print found

回答by debug

If you use requests, a simple code is here:

如果您使用requests,这里有一个简单的代码:

#!/usr/bin/python
# -*- coding: utf-8 -*-


from requests.packages.urllib3.contrib import pyopenssl as reqs


def https_cert_subject_alt_names(host, port):
    """Read subject domains in https cert from remote server"""

    x509 = reqs.OpenSSL.crypto.load_certificate(
        reqs.OpenSSL.crypto.FILETYPE_PEM,
        reqs.ssl.get_server_certificate((host, port))
    )
    return reqs.get_subj_alt_name(x509)

if __name__ == '__main__':
    domains = https_cert_subject_alt_names("www.yahoo.com", 443)
    print(domains)

The result is as follow:

结果如下:

[('DNS', '*.www.yahoo.com'), 
 ('DNS', 'www.yahoo.com'), 
 ('DNS', 'add.my.yahoo.com'), 
 ('DNS', 'au.yahoo.com'), 
 ('DNS', 'be.yahoo.com'), 
 ('DNS', 'br.yahoo.com'), 
 ('DNS', 'ca.my.yahoo.com'), 
 ('DNS', 'ca.rogers.yahoo.com'), 
 ('DNS', 'ca.yahoo.com'), 
 ('DNS', 'ddl.fp.yahoo.com'), 
 ('DNS', 'de.yahoo.com'), 
 ...
 ('DNS', 'mbp.yimg.com')]