たれながし.info

とあるITエンジニアの備忘録

サーバーのSSL/TLS証明書のフィールドをPythonで出力する

Webサーバーなどに設定されているSSL/TLSサーバー証明書について、複数サーバーの証明書のフィールドをチェックする際にどうしたら良いか?と考えた時に、プログラム書いて調べたら良いかなと思ったので、実現方法を調べてみました。


例)www.google.comに設定されているサーバー証明書

結論としては、Pythonの標準モジュール「ssl」「socket」を使ってできました。

以下サイトを参考にしました。
www.askpython.com

実施方法

サーバーの「HostName」をキーにSSL/TLSサーバー証明書のフィールドを出力するサンプルです。

「CommonName」と「期限(開始と終了)」を出力します。
サブジェクト代替名(subjectAltName/DNSName)」なども出力可能ですが、証明書によっては大量に設定されている場合があるので出力部分はコメントアウトしています。

Pythonプログラム

import ssl
import socket
 
def verify_ssl_certificate(hostname):
    context = ssl.create_default_context() 
    with socket.create_connection((hostname, 443)) as sock:
        with context.wrap_socket(sock, server_hostname=hostname) as ssock:
            ssock.do_handshake()
            cert = ssock.getpeercert()
            CommonName = get_commonname(cert["subject"])
            NotBefore = cert["notBefore"]
            NotAfter = cert["notAfter"]
            # SubjectAltName = cert["subjectAltName"]
            print(f'"{hostname}","{CommonName}","{NotBefore}","{NotAfter}"')

def get_commonname(subjects):
    for subject in subjects:
        if subject[0][0] == "commonName":
            return subject[0][1]
    return ""

if __name__ == '__main__':
    print(f'"HostName","CommonName","NotBefore", "NotAfter"')
    for hostname in ["www.yahoo.co.jp", "www.google.com"]:
        verify_ssl_certificate(hostname)

実行結果

> python check_servercert.py
"HostName","CommonName","NotBefore", "NotAfter"
"www.yahoo.co.jp","edge01.yahoo.co.jp","Jul 28 02:16:59 2023 GMT","Aug 27 14:59:00 2024 GMT"
"www.google.com","www.google.com","Oct 16 08:10:46 2023 GMT","Jan  8 08:10:45 2024 GMT"