随着业务的发展,很多域名都需要使用HTTPS。这就带来了一个新的问题:如何监控HTTPS域名证书的有效性。虽然证书不是一刹那过期的,但是也需要对其进行监控。了解其有效时间,并在过期前进行报警监控。
要完成这些功能,所限就是要对证书进行解析。对证书解析可以使用python的OpenSSL库,以下为示例代码:
import OpenSSL
import time
from dateutil import parser
cert = OpenSSL.crypto.load_certificate(OpenSSL.crypto.FILETYPE_PEM, open("hrs100.com.pem").read())
certIssue = cert.get_issuer()
print("",cert.get_subject())
print("issuer",cert.get_issuer())
print("证书版本: ",cert.get_version() +1)
print("证书序列号: ",hex(cert.get_serial_number()))
print("证书中使用的签名算法: ",cert.get_signature_algorithm().decode("UTF-8"))
print("颁发者: ",certIssue.commonName)
datetime_struct = parser.parse(cert.get_notBefore().decode("UTF-8"))
print("有效期从: ",datetime_struct.strftime('%Y-%m-%d %H:%M:%S'))
datetime_struct = parser.parse(cert.get_notAfter().decode("UTF-8"))
print("到: ",datetime_struct.strftime('%Y-%m-%d %H:%M:%S'))
print("证书是否已经过期: ",cert.has_expired())
print("公钥长度",cert.get_pubkey().bits())
print("公钥:\n",OpenSSL.crypto.dump_publickey(OpenSSL.crypto.FILETYPE_PEM, cert.get_pubkey()).decode("utf-8"))
print("主体信息:")
print("CN : 通用名称 OU : 机构单元名称")
print("O : 机构名 L : 地理位置")
print("S : 州/省名 C : 国名")
for item in certIssue.get_components():
print(item[0].decode("utf-8")," —— ",item[1].decode("utf-8"))
print(cert.get_extension_count())
这个示例是证书文件可见的情况下使用,还可以通过curl访问的方式对证书信息进行获取,以下为实例代码:
import socket
from OpenSSL import SSL
import certifi
from datetime import datetime
def convert_to_human_readable(utc_date):
# 将字节串转换为字符串
utc_date_str = utc_date.decode('utf-8')
# 解析字符串为datetime对象
utc_datetime = datetime.strptime(utc_date_str, "%Y%m%d%H%M%SZ")
# 转换为本地时间并返回
local_datetime = utc_datetime.astimezone()
return local_datetime.strftime("%Y-%m-%d %H:%M:%S")
def get_certificate_info(domain):
try:
context = SSL.Context(SSL.SSLv23_METHOD)
context.load_verify_locations(certifi.where())
conn = SSL.Connection(context, socket.socket(socket.AF_INET))
conn.connect((domain, 443))
conn.set_tlsext_host_name(domain.encode('utf-8'))
conn.do_handshake()
cert = conn.get_peer_certificate()
conn.close()
return cert
except Exception as e:
return None
def main():
domain = "baidu.com" # 您要查询的域名
certificate_info = get_certificate_info(domain)
if certificate_info:
print("证书信息:")
print("颁发者:", certificate_info.get_issuer())
print("主题:", certificate_info.get_subject())
expiration_date = certificate_info.get_notAfter()
human_readable_date = convert_to_human_readable(expiration_date)
print("过期日期:", human_readable_date)
else:
print("无法获取证书信息。")
if __name__ == "__main__":
main()
通过实例代码,可以获取证书的各种信息。其中就包括到期时间。通过对到期时间与当前时间的判断,就可以通过例如钉钉微信的工具进行通知提醒。