python 通过两种方式获取SSL证书信息
- 前言
- 原理
- 依赖
- 代码
- 结束
前言
SSL证书是数字证书的一种,类似于驾驶证、护照和营业执照的电子副本。因为配置在服务器上,也称为SSL服务器证书。
SSL 证书就是遵守 SSL协议,由受信任的数字证书颁发机构CA,在验证服务器身份后颁发,具有服务器身份验证和数据传输加密功能。
原理
X.509是ITU-T标准化部门基于他们之前的ASN.1定义的一套证书标准。X.509 证书己应用在包括TLS/SSL(WWW万维网安全浏览的基石)在内的众多 Internet协议里.
一般会包含以下的信息:
1.版本号
2.拥有者公钥
3.证书的序列号,同一个发布者范围内唯一的
4.拥有者标识,这个标识是全世界唯一的
5.证书的有效期
6.发布者的数字签名
7.签名算法的描述
X509证书文件,根据封装的不同,主要有以下三种类型:
*.cer:单个X509证书文件,不私钥,可以是二进制和Base64格式。该类型的证书最常见;
*.p7b:PKCS#7格式的证书链文件,包含一个或多个X509证书,不含私钥。通常从CA中心申请RSA证书时,返回的签名证书就是p7b格式的证书文件;
*.pfx:PKCS#12格式的证书文件,可以包含一个或者多个X509证书,含有私钥,一般有密码保护。通常从CA中心申请RSA证书时,加密证书和RSA加密私钥就是一个pfx格式的文件返回。
依赖
pip install pyOpenSSL==19.1.0
pip install python-dateutil==2.8.1
代码
第一种通过传入域名获取证书信息:
def domain_analysis(domain):
"""
# 查询域名证书到期
:param domain:
:return:
"""
try:
domain_str = "curl -Ivs https://%s --connect-timeout 10" % domain.encode("UTF-8")
return_code, output = commands.getstatusoutput(domain_str)
m = re.search('SSL connection using (.*?)\n.*?start date: (.*?)\n.*?expire date: (.*?)\n.*?issuer: (.*?)\n.*?',
output, re.S)
if m:
start_date = m.groups()[1]
expire_date = m.groups()[2]
issuer = m.groups()[3]
agreement = m.groups()[0]
# time 字符串转时间数组
start_date = time.strptime(start_date, "%b %d %H:%M:%S %Y GMT")
start_date_st = time.strftime("%Y-%m-%d %H:%M:%S", start_date)
# datetime 字符串转时间数组
expire_date = datetime.strptime(expire_date, "%b %d %H:%M:%S %Y GMT")
expire_date_st = datetime.strftime(expire_date, "%Y-%m-%d %H:%M:%S")
# 剩余天数
# remaining = (expire_date-datetime.now()).days
version = ''
encryption = ''
if agreement:
version = agreement.split(' / ')[0]
encryption = agreement.split(' / ')[1]
dic = {i.split("=")[0]: i.split("=")[1] for i in issuer.split("; ")}
return {
"domain": domain,
"start_date": start_date_st,
"expire_date": expire_date_st,
"issuer": dic['CN'],
"tls_version": version,
"encryption": encryption
}
except Exception as e:
logger.error(u'域名获取证书异常:%s' % e)
return {
"domain": domain,
"start_date": '',
"expire_date": '',
"issuer": '',
"tls_version": '',
"encryption": ''
}
第二种通过导入证书内容解析证书信息:
def check_cer(cert_str):
try:
cert = crypto.load_certificate(crypto.FILETYPE_PEM, test)
print cert
subject = cert.get_subject()
# 得到证书的域名
issued_to = subject.CN
issuer = cert.get_issuer()
# 得到证书颁发机构
issued_by = issuer.CN
#
datetime_struct = parser.parse(cert.get_notBefore().decode("UTF-8"))
datetime_struct_end = parser.parse(cert.get_notAfter().decode("UTF-8"))
# 加密算法
encryption = cert.get_signature_algorithm().decode("UTF-8")
version = cert.get_version()
return {
"domain": issued_to.encode('UTF-8'),
"start_date": datetime_struct.strftime('%Y-%m-%d %H:%M:%S'),
"expire_date": datetime_struct_end.strftime('%Y-%m-%d %H:%M:%S'),
"issuer": issued_by.encode('UTF-8'),
"tls_version": version,
"encryption": encryption
}
except Exception as e:
logger.error(u'证书解析异常:%s' % e)
return {
"domain": '',
"start_date": '',
"expire_date": '',
"issuer": '',
"tls_version": '',
"encryption": ''
}
详情参考
https://www.pyopenssl.org/en/stable/api/crypto.html?highlight=load_certificate#x509-objects
第一种调用测试结果如下(第二种方式同样的结果)。
结束