web-dev-qa-db-ja.com

Pythonで証明書発行者情報を取得するにはどうすればよいですか?

Pythonの証明書からの「発行先」情報が必要です。 SSLおよびSSLSocketライブラリを使用しようとしましたが、実行されませんでした。

enter image description here

10
Raj

回答を更新しました

リモートサーバーへの接続を確立できる場合は、ssl標準ライブラリモジュールを使用できます。

import ssl, socket

hostname = 'google.com'
ctx = ssl.create_default_context()
s = ctx.wrap_socket(socket.socket(), server_hostname=hostname)
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'

元の答え

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

追加コンポーネントにアクセスすることもできます。組織(subject.O/issuer.O)、組織単位(subject.OU/issuer.OU)。

証明書ファイルが別の形式になっている可能性があるため、crypto.FILETYPE_ASN1 の代わりに crypto.FILETYPE_PEM

24
mhawke

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)

結果は次のとおりです。

[('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')]
1
debug