前言
需求很简单,通过域名证书的私钥分析证书的 DNS
域名以及有效期
实现
分析后决定用 pyOpenSSL
来实现,具体代码如下
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
| from OpenSSL import crypto from dateutil import parser
class Ssl(): def parse(self, certificate): res = { "domain": [] } cert = crypto.load_certificate(crypto.FILETYPE_PEM, certificate) datetime_struct_start = parser.parse(cert.get_notBefore().decode("UTF-8")) datetime_struct_end = parser.parse(cert.get_notAfter().decode("UTF-8")) res['start_time'] = datetime_struct_start.strftime('%Y-%m-%d %H:%M:%S') res['end_time'] = datetime_struct_end.strftime('%Y-%m-%d %H:%M:%S') count = cert.get_extension_count() for i in range(count): crt = cert.get_extension(i) name = str(crt.get_short_name(), encoding="utf-8") if name == "subjectAltName": _list = str(crt).split(',') _it = iter(_list) for x in _it: res["domain"].append(x.strip().replace("DNS:", "")) break return res
if __name__ == '__main__': _certificate="""证书私钥""" ssl = Ssl() print(ssl.parse(_certificate))
|
最后
通过 get_subject()
和 get_issuer()
获取证书的其他信息
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| subject = cert.get_subject() issuer = cert.get_issuer()
print("证书版本:", cert.get_version() + 1) print("证书序列号:", hex(cert.get_serial_number())) print("证书中使用的签名算法:", cert.get_signature_algorithm().decode("UTF-8")) print("颁发者:", issuer.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", crypto.dump_publickey(crypto.FILETYPE_PEM, cert.get_pubkey()).decode("utf-8")) print("主体信息:") print("CN:通用名称 OU:机构单元名称") print("O:机构名 L:地理位置") print("S:州/省名 C:国名") for item in issuer.get_components(): print(item[0].decode("utf-8"), " —— ", item[1].decode("utf-8"))
|