Python获取网站的SSL证书到期时间

liftword7个月前 (12-16)技术文章91


了解证书的剩余有效期,可以在证书即将到期时自动发送警告通知。告诉管理运营人员进行续订或更新,避免服务中断。

想要使用Python获取网站的ssl证书到期时间,我们可以使用ssl模块和socket库。

提示

  • 准备将要检测的域名
  • 通过使用ssl模块和socket库获取到对端的证书信息,并解析证书中的到期时间
  • 通知处理:例如发邮件,发短信等,测试脚本我们用tabulate打印输出。
# -*- coding: UTF-8 -*-

"""
获取一个网站HTTPS证书的到期时间和剩余天数。
    pytz: 处理时区转换
    tabulate: 打印漂亮表格
"""

import socket
import ssl
from datetime import datetime
import pytz
from tabulate import tabulate


def get_certificate_info(host='', port=443):
    """
    获取指定主机HTTPS证书的信息。

    参数:
    host (str): 主机名或IP地址,默认为 ''。
    port (int): 端口,默认为 443。

    返回:
    dict: 包含证书到期时间和剩余天数的信息字典。
    """
    try:
        # 创建默认的SSL上下文
        context = ssl.create_default_context()
        # 基于默认上下文和AF_INET地址族创建一个安全的socket连接
        conn = context.wrap_socket(socket.socket(socket.AF_INET), server_hostname=host)
        # 连接到指定的主机和端口
        conn.connect((host, port))

        # 获取对端的证书信息
        cert = conn.getpeercert()
        # 尝试解析证书的过期时间
        try:
            not_after = datetime.strptime(cert['notAfter'], "%b %d %H:%M:%S %Y %Z")
        except Exception as e:
            # 如果证书的过期时间格式无法识别,则返回错误信息
            return {
                'expiry_time': "无法识别的日期格式" + e.__str__(),
                'days_remaining': "未知"
            }

        # 创建UTC时区对象
        utc_tz = pytz.utc

        # 将证书的到期时间设置为UTC时间
        not_after_utc = utc_tz.localize(not_after)

        # 创建北京时间时区对象
        beijing_tz = pytz.timezone('Asia/Shanghai')

        # 将UTC时间转换为北京时间
        not_after_bj = not_after_utc.astimezone(beijing_tz)

        # 计算剩余天数
        days_remaining = (not_after_bj - datetime.now(beijing_tz)).days

        return {
            'expiry_time': not_after_bj.strftime('%Y-%m-%d %H:%M:%S'),
            'days_remaining': days_remaining
        }
    except Exception as e:
        return {
            'expiry_time': str(e),
            'days_remaining': "未知"
        }


if __name__ == '__main__':

    # 定义一个包含多个域名的列表
    hostname_list = [
        "www.qq.com",
        "www.baidu.com",
        "www.sohu.com",
        "www.xiaomi.com",
        # 故意给个未知域名
        "www.weizhiyuming.com",
    ]

    # 初始化一个列表,用于存储主机名及其证书到期时间的相关信息
    hostname_list_result = [
        ["检测域名", "到期时间", "剩余天数"]
    ]

    # 遍历主机名列表,获取每个主机的证书信息
    for hostname in hostname_list:
        # 获取当前主机的证书信息
        cert_info = get_certificate_info(hostname)
        # 构建包含主机名、证书到期时间、剩余天数的列表
        cert_info_result = [
            hostname, cert_info['expiry_time'], cert_info['days_remaining'],
        ]
        # 将当前主机的证书信息列表添加到结果列表中
        hostname_list_result.append(cert_info_result)

    print(tabulate(hostname_list_result, tablefmt="grid", numalign="center"))


相关文章

Python编程基础:时间time模块 python time_ns

time模块提供了与时间相关的函数,本文介绍time模块的常用函数。获取时间戳:time()函数时间戳指自1970年1月1日0点0分0秒以来的总秒数(浮点数)。import time print(t...