python 通过两种方式获取SSL证书信息

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

第一种调用测试结果如下(第二种方式同样的结果)。
在这里插入图片描述

结束

  • 3
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Python接口测试中,可以使用requests库来发送HTTPS请求,并且可以通过设置verify参数来指定SSL证书。verify参数可以设置为True、False或者指定证书文件的路径。 如果设置为True,requests会验证SSL证书,如果证书无效会抛出CertificateError异常。 如果设置为False,requests会忽略SSL证书,不会验证证书的有效性,不建议在生产环境中使用。 如果指定证书文件的路径,requests会使用该证书进行验证。 示例代码如下: ```python import requests # 验证SSL证书 response = requests.get('https://www.example.com', verify=True) # 忽略SSL证书 response = requests.get('https://www.example.com', verify=False) # 指定SSL证书 response = requests.get('https://www.example.com', verify='/path/to/cert.pem') ``` 在实际测试中,如果遇到证书无效的情况,可以尝试通过以下方式解决: 1. 获取证书的SHA1指纹,将其添加到requests的信任列表中。 ```python import requests cert = ('/path/to/cert.pem', '/path/to/key.pem') # 获取证书的SHA1指纹 import hashlib fp = open(cert[0], 'rb') cert_data = fp.read() fp.close() finger_print = hashlib.sha1(cert_data).hexdigest() # 将指纹添加到requests的信任列表中 requests.utils.DEFAULT_CA_BUNDLE_PATHS.append(cert[0]) requests.utils.DEFAULT_CA_BUNDLE_PATHS.append(cert[1]) requests.utils.DEFAULT_CA_BUNDLE_PATHS.append(finger_print) # 发送HTTPS请求 response = requests.get('https://www.example.com', cert=cert) ``` 2. 禁用证书验证。 ```python import requests from requests.packages.urllib3.exceptions import InsecureRequestWarning # 禁用证书验证 requests.packages.urllib3.disable_warnings(InsecureRequestWarning) # 发送HTTPS请求 response = requests.get('https://www.example.com', verify=False) ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值