python获取https证书有效期

首先要安装一个依赖

pyOpenSSL==19.1.0

下面是简单的代码:

# coding: UTF-8


import re
import select
import socket
import OpenSSL
from datetime import datetime, timedelta


class CertInfo:
    def __init__(self, host, cert_host, start_time, end_time):
        self.host = host
        self.cert_host = cert_host
        self.start_time = datetime.strptime(start_time.decode("UTF-8"), "%Y%m%d%H%M%SZ")
        self.end_time = datetime.strptime(end_time.decode("UTF-8"), "%Y%m%d%H%M%SZ")

        now = datetime.now()
        self.warn = now + timedelta(days=10) >= self.end_time

        self.days = (self.end_time - now).days

    def __str__(self):
        return "域名:" + self.host + ",证书dns:" + self.cert_host + ",过期时间:" + self.end_time.strftime(
            "%Y-%m-%d %H:%M:%S") + ",剩余天数:" + str(
            self.days)


def _get_cert_from_domain(domain):
    ctx = OpenSSL.SSL.Context(OpenSSL.SSL.SSLv23_METHOD)
    sock = socket.socket()
    sock.settimeout(15)
    wrapped_sock = OpenSSL.SSL.Connection(ctx, sock)
    wrapped_sock.set_tlsext_host_name(domain.encode('ascii'))
    wrapped_sock.connect((domain, 443))
    while True:
        try:
            wrapped_sock.do_handshake()
            break
        except OpenSSL.SSL.WantReadError:
            select.select([wrapped_sock], [], [])
    return wrapped_sock.get_peer_cert_chain()


def check(host):
    data = _get_cert_from_domain(host)
    for cert in data:
        cert_host = cert.get_subject().get_components()[0][1].decode("UTF-8")
        re_cert_host = cert_host.replace("*", ".*")
        if not re.match(re_cert_host, host):
            continue
        return CertInfo(host, cert_host, cert.get_notBefore(), cert.get_notAfter())


if __name__ == '__main__':
    info = check("tech.yubangweb.com")
    print(info)