証明書の有効期限を確認する Python スクリプト

pyOpenSSL は OpenSSL の Python 用ラッパーです。 pyOpenSSL を使うことで python のコード内から OpenSSL を利用することが可能です。 今回は pyOpenSSL を利用して「Python から証明書の有効期限を取得する」サンプルをメモしておきます。

まず、テスト用の venv 環境を作成し、pyOpenSSL をインストールしておきます。

1
2
3
4
5
6
7
mkdir certchecker
cd certchecker
python3 -m venv .venv
echo 'source .venv/bin/activate' > .envrc
direnv allow
python3 -m pip install --upgrade pip
python3 -m pip install pyopenssl

サンプルスクリプトは以下の通りです。 今回は check-cert.py という名前にしました。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
#!/usr/bin/env python3

import datetime
import socket
import ssl
import sys

import OpenSSL


ssl._create_default_https_context = ssl._create_unverified_context


def get_server_certificate(hostname: str, port: int) -> OpenSSL.crypto.X509:
    context = ssl.create_default_context()
    with socket.create_connection((hostname, port)) as sock:
        with context.wrap_socket(sock, server_hostname=hostname) as sslsock:
            der_cert = sslsock.getpeercert(True)
            return ssl.DER_cert_to_PEM_cert(der_cert)


def get_not_before(x509: OpenSSL.crypto.X509) -> datetime.datetime:
    return datetime.datetime.strptime(
        str(x509.get_notBefore())[2:16], "%Y%m%d%H%M%S"
    ) + datetime.timedelta(hours=9)


def get_not_after(x509: OpenSSL.crypto.X509) -> datetime.datetime:
    return datetime.datetime.strptime(
        str(x509.get_notAfter())[2:16], "%Y%m%d%H%M%S"
    ) + datetime.timedelta(hours=9)


def get_remaining(x509: OpenSSL.crypto.X509) -> datetime.datetime:
    return get_not_after(x509) - datetime.datetime.now()


def get_remaining_days(x509: OpenSSL.crypto.X509) -> int:
    return int(get_remaining(x509).days)


cert = get_server_certificate(sys.argv[1], 443)
x509 = OpenSSL.crypto.load_certificate(
    OpenSSL.crypto.FILETYPE_PEM, cert.encode("utf-8")
)

not_before = str(get_not_before(x509))
not_after = str(get_not_after(x509))
remaining = str(get_remaining(x509))
days = get_remaining_days(x509)

print("Not Before     : " + not_before)
print("Not After      : " + not_after)
print("Remaing        : " + remaining)
print("Remaining Days : " + str(days))

実行例は以下の通りです。

1
2
3
4
5
# ./check-cert.py www.google.com
Not Before     : 2022-04-11 18:43:41
Not After      : 2022-07-04 18:43:40
Remaing        : 60 days, 5:08:18.263484
Remaining Days : 60