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

第一种调用测试结果如下(第二种方式同样的结果)。

Python有关的PPT python有关的证_Python有关的PPT

结束