python獲取域名ssl證書信息和到期時間
文檔
https://docs.python.org/zh-cn/3/library/socket.html
https://docs.python.org/zh-cn/3/library/ssl.html
1、通過openssl證書獲取
openssl x509 -in <cert>.pem -noout -dates
2、通過openssl域名獲取
echo | openssl s_client -servername <doman> -connect <doman>:443 2>/dev/null | openssl x509 -noout -dates
3、通過腳本獲取curl
#?coding:?utf-8? #?查詢域名證書到期情況 import?re import?subprocess from?datetime?import?datetime def?get_re_match_result(pattern,?string): ????match?=?re.search(pattern,?string) ????return?match.group(1) def?parse_time(date_str): ????return?datetime.strptime(date_str,?"%b?%d?%H:%M:%S?%Y?GMT") def?format_time(date_time): ????return?datetime.strftime(date_time,?"%Y-%m-%d?%H:%M:%S") def?get_cert_info(domain): ????"""獲取證書信息""" ????cmd?=?f"curl?-Ivs?https://{domain}?--connect-timeout?10" ????exitcode,?output?=?subprocess.getstatusoutput(cmd) ????#?正則匹配 ????start_date?=?get_re_match_result('start?date:?(.*)',?output) ????expire_date?=?get_re_match_result('expire?date:?(.*)',?output) ????#?解析匹配結(jié)果 ????start_date?=?parse_time(start_date) ????expire_date?=?parse_time(expire_date) ????return?{ ????????'start_date':?start_date, ????????'expire_date':?expire_date ????} def?get_cert_expire_date(domain): ????"""獲取證書剩余時間""" ????info?=?get_cert_info(domain) ????print(info) ????expire_date?=?info['expire_date'] ????#?剩余天數(shù) ????return?(expire_date?-?datetime.now()).days if?__name__?==?"__main__": ????domain?=?'www.baidu.com' ????expire_date?=?get_cert_expire_date(domain) ????print(expire_date)
4、通過socket 獲取域名ssl 證書信息
核心代碼
#?-*-?coding:?utf-8?-*- import?socket import?ssl def?get_domain_cert(domain): ????""" ????獲取證書信息 ????:param?domain:?str ????:return:?dict ????""" ????socket.setdefaulttimeout(5) ????cxt?=?ssl.create_default_context() ????skt?=?cxt.wrap_socket(socket.socket(),?server_hostname=domain) ????skt.connect((domain,?443)) ????cert?=?skt.getpeercert() ????skt.close() ????return?cert if?__name__?==?"__main__": ????print(get_domain_cert("www.baidu.com"))
還有一種方式也記錄一下
import?socket import?ssl def?get_domain_cert(host,?port=443,?timeout=3): ????""" ????獲取證書信息 ????存在問題:沒有指定主機ip,不一定能獲取到正確的證書信息 ????:param?host:?str ????:param?port:?int ????:param?timeout:?int ????:return:?dict ????""" ????context?=?ssl.create_default_context() ????with?socket.create_connection(address=(host,?port),?timeout=timeout)?as?sock: ????????with?context.wrap_socket(sock,?server_hostname=host)?as?wrap_socket: ????????????return?wrap_socket.getpeercert()
輸出
{
'subject': ((('countryName', 'CN'),), (('stateOrProvinceName', 'beijing'),), (('localityName', 'beijing'),), (('organizationalUnitName', 'service operation department'),), (('organizationName', 'Beijing Baidu Netcom Science Technology Co., Ltd'),), (('commonName', 'baidu.com'),)),
'issuer': ((('countryName', 'BE'),), (('organizationName', 'GlobalSign nv-sa'),), (('commonName', 'GlobalSign RSA OV SSL CA 2018'),)),
'version': 3,
'serialNumber': '4417CE86EF82EC6921CC6F68',
'notBefore': 'Jul 5 05:16:02 2022 GMT',
'notAfter': 'Aug 6 05:16:01 2023 GMT',
'subjectAltName': (('DNS', 'baidu.com'), ),
'OCSP': ('http://ocsp.globalsign.com/gsrsaovsslca2018',),
'caIssuers': ('http://secure.globalsign.com/cacert/gsrsaovsslca2018.crt',),
'crlDistributionPoints': ('http://crl.globalsign.com/gsrsaovsslca2018.crl',)
}
結(jié)構(gòu)化輸出內(nèi)容后的完整代碼
#?-*-?coding:?utf-8?-*- import?socket import?ssl from?dateutil?import?parser #?requests.packages.urllib3.disable_warnings() try: ????_create_unverified_https_context?=?ssl._create_unverified_context except?AttributeError: ????#?Legacy?Python?that?doesn't?verify?HTTPS?certificates?by?default ????pass else: ????#?Handle?target?environment?that?doesn't?support?HTTPS?verification ????ssl._create_default_https_context?=?_create_unverified_https_context DATETIME_FORMAT?=?'%Y-%m-%d?%H:%M:%S' socket.setdefaulttimeout(5) def?get_domain_ip(domain): ????""" ????獲取ip地址 ????:param?domain:?str ????:return:?str ????""" ????try: ????????addrinfo?=?socket.getaddrinfo(domain,?None) ????????return?addrinfo[0][-1][0] ????except?Exception?as?e: ????????pass ????return?None def?get_domain_cert(domain): ????""" ????獲取證書信息 ????:param?domain:?str ????:return:?dict ????""" ????cxt?=?ssl.create_default_context() ????skt?=?cxt.wrap_socket(socket.socket(),?server_hostname=domain) ????skt.connect((domain,?443)) ????cert?=?skt.getpeercert() ????skt.close() ????return?cert def?get_cert_info(domain): ????""" ????獲取證書信息 ????:param?domain:?str ????:return:?dict ????""" ????cert?=?get_domain_cert(domain) ????issuer?=?_tuple_to_dict(cert['issuer']) ????subject?=?_tuple_to_dict(cert['subject']) ????return?{ ????????'domain':?domain, ????????'ip':?get_domain_ip(domain), ????????'subject':?_name_convert(subject), ????????'issuer':?_name_convert(issuer), ????????#?'version':?cert['version'], ????????#?'serial_number':?cert['serialNumber'], ????????'start_date':?_parse_time(cert['notBefore']), ????????'expire_date':?_parse_time(cert['notAfter']), ????} def?_tuple_to_dict(cert_tuple): ????""" ????cert證書?tuple轉(zhuǎn)dict ????:param?cert_tuple:?tuple ????:return: ????""" ????data?=?{} ????for?item?in?cert_tuple: ????????data[item[0][0]]?=?item[0][1] ????return?data def?_name_convert(data): ????""" ????名字轉(zhuǎn)換 ????:param?data:?dict ????:return:?dict ????""" ????name_map?=?{ ????????'C':?'countryName', ????????'CN':?'commonName', ????????'O':?'organizationName', ????????'OU':?'organizationalUnitName', ????????'L':?'localityName', ????????'ST':?'stateOrProvinceName' ????} ????dct?=?{} ????for?key,?value?in?name_map.items(): ????????dct[key]?=?data.get(value,?'') ????return?dct def?_parse_time(time_str): ????""" ????解析并格式化時間 ????:param?time_str:?str ????:return:?str ????""" ????return?parser.parse(time_str).astimezone().strftime(DATETIME_FORMAT) if?__name__?==?"__main__": ????print(get_cert_info("www.baidu.com"))
輸出
{
"domain": "www.baidu.com",
"ip": "39.156.66.14",
"subject": {
"C": "CN",
"CN": "baidu.com",
"O": "Beijing Baidu Netcom Science Technology Co., Ltd",
"OU": "service operation department",
"L": "beijing",
"ST": "beijing"
},
"issuer": {
"C": "BE",
"CN": "GlobalSign RSA OV SSL CA 2018",
"O": "GlobalSign nv-sa",
"OU": "",
"L": "",
"ST": ""
},
"start_date": "2022-07-05 13:16:02",
"expire_date": "2023-08-06 13:16:01"
}
5、通過pyOpenSSL獲取證書信息
該方式,不校驗證書合法性,只獲取證書信息
文檔:https://pyopenssl.org/en/0.15.1/index.html#
依賴
pip?install?pyOpenSSL
示例
#?-*-?coding:?utf-8?-*- import?ssl import?OpenSSL def?get_ssl_expire_date(host,?port=443): ????cert?=?ssl.get_server_certificate((host,?port)) ????x509?=?OpenSSL.crypto.load_certificate(OpenSSL.crypto.FILETYPE_PEM,?cert) ????return?x509.get_notAfter().decode() if?__name__?==?'__main__': ????print(get_ssl_expire_date('www.baidu.com')) ????#?20230806051601Z
6、Domain Admin可視化管理域名證書到期
項目地址:https://github.com/mouday/domain-admin
運行環(huán)境:Python 3.7.0
$?pip?install?domain_admin #?升級到最新版本,可選 $?pip3?install?-U?domain-admin?-i?https://pypi.org/simple #?啟動運行 $?gunicorn?'domain_admin.main:app'
訪問地址:http://127.0.0.1:8000
默認的管理員賬號:admin 密碼:123456
以上就是python獲取域名ssl證書信息和到期時間的詳細內(nèi)容,更多關(guān)于python ssl的資料請關(guān)注腳本之家其它相關(guān)文章!