【问题标题】:How to fetch the SSL certificate to see whether it's expired or not如何获取 SSL 证书以查看它是否已过期
【发布时间】:2017-08-22 06:11:22
【问题描述】:

我没有从这段代码中得到任何输出。好消息是我没有收到任何错误。请告诉我哪里做错了。这是我的代码或任何其他查找 ssl 过期日期的方法证书(仅使用 Python)

import datetime
import logging
import socket
import ssl

YOUR_DOMAIN = 'google.com'
WARNING_BUFFER = 14

logger = logging.getLogger()
logger.setLevel(logging.INFO)

ssl_date_fmt = r'%b %d %H:%M:%S %Y %Z'

class AlreadyExpired(Exception):
    pass

def ssl_expires_in(hostname, buffer_days=14):
    """Gets the SSL cert from a given hostname and checks if it expires within buffer_days"""
    context = ssl.create_default_context()
    conn = context.wrap_socket(
        socket.socket(socket.AF_INET),
        server_hostname=hostname,

    )
    # 3 second timeout because Lambda has runtime limitations
    conn.settimeout(3.0)
    conn.connect((hostname, 443))
    ssl_info = conn.getpeercert()
    expires = datetime.datetime.strptime(ssl_info['notAfter'], ssl_date_fmt)

    # if the cert expires in less than two weeks, we should reissue it
    if expires < (datetime.datetime.utcnow() + datetime.timedelta(days=buffer_days)):
        # expires sooner than the buffer
        return True
    elif expires < datetime.datetime.utcnow():
        # cert has already expired - uhoh!
        raise AlreadyExpired("Cert expired at %s" % ssl_info['notAfter'])
    else:
        # everything is fine
        return False


def lambda_handler(event, context):
    try:
        if not ssl_expires_in(YOUR_DOMAIN, WARNING_BUFFER):
            logger.info("SSL certificate doesn't expire for a while - you're set!")
            return {"success": True, "cert_status": "valid"}
        else:
            logger.warning("SSL certificate expires soon")
            return {"success": True, "cert_status": "expiring soon"}
    except AlreadyExpired as e:
        logger.exception("Certificate is expired, get worried!")
        return {"success": True, "cert_status": "expired"}
    except Exception as e:
        logger.exception("Failed to get certificate info")
        return {"success": False, "cert_status": "unknown"}

【问题讨论】:

    标签: python ssl plugins


    【解决方案1】:

    您可以使用“pyOpenSSL”(pip install pyOpenSSL) 和“ssl”(python 内置)包来实现。

    import ssl
    import OpenSSL
    
    def get_SSL_Expiry_Date(host, port):
        cert = ssl.get_server_certificate((host, port))
        x509 = OpenSSL.crypto.load_certificate(OpenSSL.crypto.FILETYPE_PEM, cert)
        print(x509.get_notAfter())
    
    get_SSL_Expiry_Date("google.com", 443)
    

    输出:b'20181113080500Z'

    或者你可以像这样只用 python 来做:

    import ssl
    import socket
    import datetime
    
    def ssl_expiry_datetime(host, port=443):
        ssl_date_fmt = r'%b %d %H:%M:%S %Y %Z'
    
        context = ssl.create_default_context()
        conn = context.wrap_socket(
            socket.socket(socket.AF_INET),
            server_hostname=host,
        )
        # 3 second timeout because Lambda has runtime limitations
        conn.settimeout(3.0)
        conn.connect((host, port))
        ssl_info = conn.getpeercert()
        print(ssl_info)
        # parse the string from the certificate into a Python datetime object
        res = datetime.datetime.strptime(ssl_info['notAfter'], ssl_date_fmt)
        return res
    
    print(ssl_expiry_datetime("google.com"))
    

    输出:2018-11-13 08:04:00

    【讨论】:

    • 没有第二个选项不起作用。它会失败并出现错误 [SSL: CERTIFICATE_VERIFY_FAILED] 证书验证失败 (_ssl.c:833)
    • 你能告诉它失败的域名吗?我试过了,对我来说效果很好。
    • 第二种方法不适用于任何主机名的过期 ssl 证书。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-11-08
    • 2013-10-10
    • 1970-01-01
    • 2021-11-29
    • 1970-01-01
    • 2020-09-18
    • 1970-01-01
    相关资源
    最近更新 更多