# -*- encoding: utf-8 -*-
# requires a recent enough python with idna support in socket
# pyopenssl, cryptography and idna
from OpenSSL import SSL
from cryptography import x509
from cryptography.x509.oid import NameOID
import idna
from socket import socket
from collections import namedtuple
HostInfo = namedtuple(field_names='cert hostname peername', typename='HostInfo')
HOSTS = [
('damjan.softver.org.mk', 443),
('expired.badssl.com', 443),
('wrong.host.badssl.com', 443),
('www.aliyun.com', 443),
('www.qq.com', 443),
('www.163.com', 443),
]
def verify_cert(cert, hostname):
# verify notAfter/notBefore, CA trusted, servername/sni/hostname
cert.has_expired()
# service_identity.pyopenssl.verify_hostname(client_ssl, hostname)
# issuer
def get_certificate(hostname, port):
hostname_idna = idna.encode(hostname)
sock = socket()
sock.connect((hostname, port))
peername = sock.getpeername()
ctx = SSL.Context(SSL.SSLv23_METHOD) # most compatible
ctx.check_hostname = False
ctx.verify_mode = SSL.VERIFY_NONE
sock_ssl = SSL.Connection(ctx, sock)
sock_ssl.set_connect_state()
sock_ssl.set_tlsext_host_name(hostname_idna)
sock_ssl.do_handshake()
cert = sock_ssl.get_peer_certificate()
crypto_cert = cert.to_cryptography()
sock_ssl.close()
sock.close()
return HostInfo(cert=crypto_cert, peername=peername, hostname=hostname)
def get_alt_names(cert):
try:
ext = cert.extensions.get_extension_for_class(x509.SubjectAlternativeName)
return ext.value.get_values_for_type(x509.DNSName)
except x509.ExtensionNotFound:
return None
def get_common_name(cert):
try:
names = cert.subject.get_attributes_for_oid(NameOID.COMMON_NAME)
return names[0].value
except x509.ExtensionNotFound:
return None
def get_issuer(cert):
try:
names = cert.issuer.get_attributes_for_oid(NameOID.COMMON_NAME)
return names[0].value
except x509.ExtensionNotFound:
return None
def print_basic_info(hostinfo):
s = '''» {hostname} « … {peername}
\tcommonName: {commonname}
\tSAN: {SAN}
\tissuer: {issuer}
\tnotBefore: {notbefore}
\tnotAfter: {notafter}
'''.format(
hostname=hostinfo.hostname,
peername=hostinfo.peername,
commonname=get_common_name(hostinfo.cert),
SAN=get_alt_names(hostinfo.cert),
issuer=get_issuer(hostinfo.cert),
notbefore=hostinfo.cert.not_valid_before,
notafter=hostinfo.cert.not_valid_after
)
print(s)
def check_it_out(hostname, port):
hostinfo = get_certificate(hostname, port)
print_basic_info(hostinfo)
import concurrent.futures
if __name__ == '__main__':
with concurrent.futures.ThreadPoolExecutor(max_workers=4) as e:
for hostinfo in e.map(lambda x: get_certificate(x[0], x[1]), HOSTS):
print_basic_info(hostinfo)
#output
» www.aliyun.com « … ('106.11.62.15', 443)
commonName: *.aliyun.com
SAN: ['*.aliyun.com', 'manager.channel.aliyun.com', '*.ace.aliyun.com', '*.acs.aliyun.com', '*.aicrowd.aliyun.com', '*.alibabacloud.co.in', '*.alibabacloud.com', '*.alibabacloud.com.au', '*.alibabacloud.com.hk', '*.alibabacloud.com.my', '*.alibabacloud.com.sg', '*.alibabacloud.com.tw', '*.alicdn.com', '*.alicloud.com', '*.aligroup.aliyun.com', '*.alimei.com', '*.alink.aliyun.com', '*.alios.aliyuncs.com', '*.aliplus.com', '*.alitranx.aliyun.com', '*.aliyun-iot-share.com', '*.aliyuncs.com', '*.ap-northeast-1.aliyuncs.com', '*.ap-south-1.aliyuncs.com', '*.ap-southeast-1.aliyuncs.com', '*.ap-southeast-2.aliyuncs.com', '*.ap-southeast-3.aliyuncs.com', '*.ap-southeast-5.aliyuncs.com', '*.apm.aliyun.com', '*.app.aliyun.com', '*.base.shuju.aliyun.com', '*.bi.aliyun.com', '*.biz.aliyun.com', '*.bridge.aliyun.com', '*.center.aliyun.com', '*.citybrain.aliyun.com', '*.cloudapp.aliyun.com', '*.cn-beijing.aliyuncs.com', '*.cn-chengdu.aliyuncs.com', '*.cn-guizhou.aliyuncs.com', '*.cn-haidian.aliyuncs.com', '*.cn-hangzhou-finance.aliyuncs.com', '*.cn-hangzhou.aliyuncs.com', '*.cn-hongkong.aliyuncs.com', '*.cn-huhehaote.aliyuncs.com', '*.cn-ningxia.aliyuncs.com', '*.cn-north-2-gov-1.aliyuncs.com', '*.cn-qingdao-nebula.aliyuncs.com', '*.cn-qingdao.aliyuncs.com', '*.cn-shanghai-finance-1.aliyuncs.com', '*.cn-shanghai.aliyun.com', '*.cn-shanghai.aliyuncs.com', '*.cn-shenzhen-cloudstone.aliyuncs.com', '*.cn-shenzhen-finance-1.aliyuncs.com', '*.cn-shenzhen.aliyuncs.com', '*.cn-sichuan.aliyuncs.com', '*.cn-zhangjiakou.aliyuncs.com', '*.connect.aliyun.com', '*.console.alibabacloud.com', '*.console.aliyun.com', '*.cs.aliyun.com', '*.cschat-ccs.aliyun.com', '*.data.aliyun.com', '*.dataapi.aliyun.com', '*.datav.aliyun.com', '*.datav.aliyuncs.com', '*.ditu.aliyun.com', '*.ebs.aliyun.com',
'*.emas.aliyun.com', '*.emr.aliyun.com', '*.enterprise.aliyun.com', '*.eu-central-1.aliyuncs.com', '*.eu-west-1.aliyuncs.com', '*.feedback.console.aliyun.com', '*.help-ccs.aliyun.com', '*.in-mumbai.aliyuncs.com', '*.iot.aliyun.com', '*.jp-fudao.aliyuncs.com', '*.linkedmall.aliyun.com', '*.linkwan.aliyun.com', '*.luban.aliyun.com', '*.market.aliyun.com', '*.maxcompute.aliyun.com', '*.me-east-1.aliyuncs.com', '*.media.aliyun.com', '*.microdingtalk.aliyun.com', '*.mobile.aliyun.com', '*.mts.aliyun.com', '*.mvp.aliyun.com', '*.nls.aliyuncs.com', '*.odps.aliyun.com', '*.ons.aliyun.com', '*.ose.aliyun.com', '*.pai.data.aliyun.com', '*.pcs-gw-cn-beijing.aliyun.com', '*.pcs-gw-cn-shanghai.aliyun.com', '*.phpwind.com', '*.phpwind.net', '*.pre-sg-purchase.aliyun.com', '*.product.center.aliyun.com', '*.pts.aliyun.com', '*.r-app-cn-beijing-data.aliyun.com', '*.r-app-cn-hangzhou-data.aliyun.com', '*.r-app-cn-shenzhen-data.aliyun.com', '*.r-app-data.aliyun.com', '*.rdc.aliyun.com', '*.rds.aliyun.com', '*.shuju.aliyun.com', '*.smart.aliyun.com', '*.soc.aliyun.com', '*.soc.aliyuncs.com', '*.sparenode.com', '*.supet.com', '*.tburl.in', '*.teambition.com', '*.teambition.net', '*.teambitionapis.com', '*.tianchi.aliyun.com', '*.toolkit.aliyun.com', '*.tv.aliyun.com', '*.tw-gaoxiong.aliyuncs.com', '*.us-east-1.aliyuncs.com', '*.us-west-1.aliyuncs.com', '*.webide.aliyun.com', 'account.www.net.cn', 'alibabacloud.co.in', 'alibabacloud.com', 'alibabacloud.com.au', 'alibabacloud.com.hk', 'alibabacloud.com.my', 'alibabacloud.com.sg', 'alibabacloud.com.tw', 'alicdn.com', 'alicloud.com', 'alimei.com', 'aliyun-iot-share.com', 'aliyuncs.com', 'dc.www.net.cn', 'dmp.www.net.cn', 'dns.www.net.cn', 'panda.www.net.cn', 'pandavip.www.net.cn', 'phpwind.com', 'phpwind.net', 'sparenode.com', 'supet.com', 'tburl.in', 'teambition.com', 'teambition.net', 'teambitionapis.com', 'tianchi-global.com', 'whois.www.net.cn', 'aliyun.com']
issuer: GlobalSign Organization Validation CA - SHA256 - G2
notBefore: 2019-07-11 01:57:02
notAfter: 2020-02-16 06:16:05
» www.qq.com « … ('14.18.175.154', 443)
commonName: www.qq.com
SAN: ['www.qq.com', '10years.qq.com', '2010.qq.com', '2011.qq.com', '2012.qq.com', '2014.qq.com', '2016.qq.com', '2018.qq.com', '3g.tech.qq.com', '61.qq.com', 'arsenal.qq.com', 'astro.fashion.qq.com', 'astro.lady.qq.com', 'astro.qq.com', 'australianopen.qq.com', 'auto.qq.com', 'baby.qq.com', 'bar.tech.qq.com', 'bbs.list.qq.com', 'bella.qq.com', 'bi.qq.com', 'biznext.qq.com', 'bj.jjj.qq.com', 'bj.qq.com', 'bj2022.qq.com', 'boao.qq.com', 'business.qq.com', 'bwf.sports.qq.com', 'campus.qq.com', 'cd.qq.com', 'cdpanda.qq.com', 'china.qq.com', 'city.qq.com', 'cost.qq.com', 'cp.qq.com', 'cq.qq.com', 'cul.qq.com', 'cy.qq.com', 'dajia.qq.com', 'dalian.qq.com', 'dao.qq.com', 'dao.rushidao.qq.com', 'data.auto.qq.com', 'data.re.qq.com', 'digi.qq.com', 'digi.tech.qq.com', 'economy.qq.com', 'edu.qq.com', 'en.2012.qq.com', 'ent.qq.com', 'euro2012.qq.com', 'fact.qq.com', 'fans.sports.qq.com', 'fashion.qq.com', 'fcbarcelona.qq.com', 'finance.qq.com', 'fj.qq.com', 'fo.rushidao.qq.com', 'foxue.qq.com', 'futsal.sports.qq.com', 'games.qq.com', 'gd.qq.com', 'golf.qq.com', 'gongyi.qq.com', 'green.news.qq.com', 'gy.qq.com', 'gz2010.qq.com', 'hanhan.qq.com', 'hb.jjj.qq.com', 'hb.qq.com', 'hea.qq.com', 'health.qq.com', 'hebei.qq.com', 'henan.qq.com', 'history.news.qq.com', 'history.qq.com', 'hn.qq.com', 'hoop.qq.com', 'house.qq.com', 'i.match.qq.com', 'iaio.qq.com', 'iapp.xw.qq.com', 'ilike.qq.com', 'ipad.qq.com', 'irs.qq.com', 'it.qq.com', 'jiaju.qq.com', 'jjj.qq.com', 'joke.qq.com', 'joy.qq.com', 'js.qq.com', 'kbs.qq.com', 'kbs.sports.qq.com', 'kepu.qq.com', 'kid.qq.com', 'kxyx.qq.com', 'learning.qq.com', 'lequipe.qq.com', 'libs.qq.com', 'liuxiang.qq.com', 'ln.qq.com', 'luxury.qq.com', 'ly.qq.com', 'm.nbachina.qq.com', 'mapp.qq.com', 'media.news.qq.com', 'media.qq.com', 'mil.qq.com', 'mini.qq.com', 'mini2015.qq.com', 'minisite.qq.com', 'minisite2009.qq.com', 'minisite2012.qq.com', 'money.finance.qq.com', 'money.qq.com', 'nba.sports.qq.com', 'nba.stats.qq.com', 'nbachina.qq.com', 'new.qq.com', 'news.qq.com', 'newsapp.qq.com', 'o.xw.qq.com', 'panel.qq.com', 'piu.qq.com', 'privacy.qq.com', 'qos.report.qq.com', 'rain.qq.com', 're.qq.com', 'report.news.qq.com', 'rss.qq.com', 'ru.qq.com', 'ru.rushidao.qq.com', 'rufodao.qq.com', 'sh.qq.com', 'soccer.qq.com', 'soccer.stats.qq.com', 'society.qq.com', 'space.qq.com', 'sports.qq.com', 'stats.2016.qq.com', 'steve-jobs.qq.com', 'stock.qq.com', 'super.dw.qq.com', 'sz.qq.com', 't.news.qq.com', 'tech.qq.com', 'thinker.qq.com', 'thr.qq.com', 'tianqi.qq.com', 'time.qq.com', 'tj.jjj.qq.com', 'tj.qq.com', 'tnw.qq.com', 'torch.2011.qq.com', 'trend.cq.qq.com', 'v.ent.qq.com', 'v.fashion.qq.com', 'v.news.qq.com', 'v.sports.qq.com', 'value.qq.com', 'vhot.qq.com', 'view.news.qq.com', 'view.yutu.qq.com', 'vip.sports.qq.com', 'vlike.qq.com', 'vs.qq.com', 'w.auto.qq.com', 'wc.qq.com', 'wcba.sports.qq.com', 'weather.news.qq.com', 'weather.qq.com', 'wimbledon.qq.com', 'world.qq.com', 'worldcup.qq.com', 'www.worldcup.qq.com', 'wxn.qq.com', 'xian.news.qq.com', 'xian.qq.com', 'xnc.sports.qq.com', 'xprize.qq.com', 'xw.qq.com', 'xw.tianqi.qq.com', 'xw.time.qq.com', 'yslp.qq.com', 'zj.qq.com',
'zp.cq.qq.com', 'zt.news.qq.com', 'qq.com']
issuer: Secure Site CA G2
notBefore: 2019-08-16 00:00:00
notAfter: 2020-08-19 12:00:00
» www.163.com « … ('183.47.233.12', 443)
commonName: *.163.com
SAN: ['*.163.com', '163.com']
issuer: GeoTrust RSA CA 2018
notBefore: 2018-12-20 00:00:00
notAfter: 2020-03-20 12:00:00
网友评论