使用pythn脚本获取服务器ssl证书的Common Name


1.使用python自带的ssl库来获取证书Common Name

由于自带的ssl库功能比较弱,如果指定ca证书时,在获取对应的证书数据时,一般会返回空,因此需要先准备好ca证书,可以使用http://curl.haxx.se/docs/caextract.html上面的

cacert.pem

使用以下脚本来获取CommanName

import socket
import ssl

ip='65.55.85.12'
s = socket.socket()
s.settimeout(10)
c = ssl.wrap_socket(s, cert_reqs=ssl.CERT_REQUIRED, ca_certs='cacert.pem')
c.settimeout(10)
print( "try connect to %s" % (ip))
c.connect((ip, 443))
cert = c.getpeercert()
print cert
如果可以正常连接,结果应该类似下面的结果

try connect to 65.55.85.12
{'notAfter': 'May 22 23:59:59 2015 GMT', 'subjectAltName': (('DNS', 'mail.live.com'), ('DNS', 'm.mail.live.com'), ('DNS', 'contacts.live.com'), ('DNS', 'hotmail.co.jp'), ('DNS', 'hotmail.co.uk'), ('DNS', 'hotmail.com'), ('DNS', 'hotmail.live.com'), ('DNS', 'hotmail.msn.com'), ('DNS', 'people.live.com'), ('DNS', 'www.hotmail.com'), ('DNS', 'www.hotmail.msn.com'), ('DNS', 'www.mail.live.com'), ('DNS', 'home.live.com'), ('DNS', 'www.live.com'), ('DNS', 'dvt.mail.live.com'), ('DNS', 'snt002.afx.ms'), ('DNS', 'snt002.mail.live.com'), ('DNS', 'snt110.afx.ms'), ('DNS', 'snt110.mail.live.com'), ('DNS', 'snt111.afx.ms'), ('DNS', 'snt111.mail.live.com'), ('DNS', 'snt112.afx.ms'), ('DNS', 'snt112.mail.live.com'), ('DNS', 'snt113.afx.ms'), ('DNS', 'snt113.mail.live.com'), ('DNS', 'snt114.afx.ms'), ('DNS', 'snt114.mail.live.com'), ('DNS', 'snt115.afx.ms'), ('DNS', 'snt115.mail.live.com'), ('DNS', 'snt116.afx.ms'), ('DNS', 'snt116.mail.live.com'), ('DNS', 'snt117.afx.ms'), ('DNS', 'snt117.mail.live.com'), ('DNS', 'snt118.afx.ms'), ('DNS', 'snt118.mail.live.com'), ('DNS', 'snt120.afx.ms'), ('DNS', 'snt120.mail.live.com'), ('DNS', 'snt121.afx.ms'), ('DNS', 'snt121.mail.live.com'), ('DNS', 'snt122.afx.ms'), ('DNS', 'snt122.mail.live.com'), ('DNS', 'snt123.afx.ms'), ('DNS', 'snt123.mail.live.com'), ('DNS', 'snt124.afx.ms'), ('DNS', 'snt124.mail.live.com'), ('DNS', 'snt125.afx.ms'), ('DNS', 'snt125.mail.live.com'), ('DNS', 'snt126.afx.ms'), ('DNS', 'snt126.mail.live.com'), ('DNS', 'snt127.afx.ms'), ('DNS', 'snt127.mail.live.com'), ('DNS', 'snt128.afx.ms'), ('DNS', 'snt128.mail.live.com'), ('DNS', 'snt129.afx.ms'), ('DNS', 'snt129.mail.live.com'), ('DNS', 'snt130.afx.ms'), ('DNS', 'snt130.mail.live.com'), ('DNS', 'snt131.afx.ms'), ('DNS', 'snt131.mail.live.com'), ('DNS', 'snt132.afx.ms'), ('DNS', 'snt132.mail.live.com'), ('DNS', 'snt133.afx.ms'), ('DNS', 'snt133.mail.live.com'), ('DNS', 'snt134.afx.ms'), ('DNS', 'snt134.mail.live.com'), ('DNS', 'snt135.afx.ms'), ('DNS', 'snt135.mail.live.com'), ('DNS', 'snt136.afx.ms'), ('DNS', 'snt136.mail.live.com'), ('DNS', 'snt137.afx.ms'), ('DNS', 'snt137.mail.live.com'), ('DNS', 'snt138.afx.ms'), ('DNS', 'snt138.mail.live.com'), ('DNS', 'snt139.afx.ms'), ('DNS', 'snt139.mail.live.com'), ('DNS', 'snt140.afx.ms'), ('DNS', 'snt140.mail.live.com'), ('DNS', 'snt141.afx.ms'), ('DNS', 'snt141.mail.live.com'), ('DNS', 'snt142.afx.ms'), ('DNS', 'snt142.mail.live.com'), ('DNS', 'snt143.afx.ms'), ('DNS', 'snt143.mail.live.com'), ('DNS', 'snt144.afx.ms'), ('DNS', 'snt144.mail.live.com'), ('DNS', 'snt145.afx.ms'), ('DNS', 'snt145.mail.live.com'), ('DNS', 'snt146.afx.ms'), ('DNS', 'snt146.mail.live.com'), ('DNS', 'snt147.afx.ms'), ('DNS', 'snt147.mail.live.com'), ('DNS', 'snt148.afx.ms'), ('DNS', 'snt148.mail.live.com')), 'subject': ((('1.3.6.1.4.1.311.60.2.1.3', u'US'),), (('1.3.6.1.4.1.311.60.2.1.2', u'Washington'),), (('businessCategory', u'Private Organization'),), (('serialNumber', u'600413485'),), (('countryName', u'US'),), (('postalCode', u'98052'),), (('stateOrProvinceName', u'Washington'),), (('localityName', u'Redmond'),), (('streetAddress', u'1 Microsoft Way'),), (('organizationName', u'Microsoft Corporation'),), (('organizationalUnitName', u'Outlook Kahuna SNT-DC A May2013'),), (('commonName', u'mail.live.com'),))}

其中subject里面的commonName就是需要获取的结果

2.使用pyOpenSSL库来获取证书Common Name

python自带的ssl库获取的内容太少,可以用第三方pyOpenSSL库获取,该库是对openssl的封装,因此提供的操作会更多,获取的内容会更丰富

在ubuntu中安装pyOpenSSL比较简单,这里就不再说明,win下安装比较麻烦,由于自带的python ssl库已满足我的需求,因此在尝试安装pyOpenSSL失败后,就不再尝试,以下的结果是从ubuntu中执行的

python openssl2.py 
65.55.85.12 try to handshake 
issuer:  
subject:  [('UNDEF', 'US'), ('UNDEF', 'Washington'), ('businessCategory', 'Private Organization'), ('serialNumber', '600413485'), ('C', 'US'), ('postalCode', '98052'), ('ST', 'Washington'), ('L', 'Redmond'), ('street', '1 Microsoft Way'), ('O', 'Microsoft Corporation'), ('OU', 'Outlook Kahuna SNT-DC A May2013'), ('CN', 'mail.live.com')]
subject里面的CN就是需要获取的内容

脚本的内容如下

from socket import socket 
from OpenSSL.SSL import Connection, Context, SSLv3_METHOD,TLSv1_METHOD,WantReadError
sslcontext = Context(SSLv3_METHOD)
sslcontext.set_timeout(30)
ip='65.55.85.12'
s = socket()
s.connect((ip, 443))
c = Connection(sslcontext, s)
c.set_connect_state()
print "%s try to handshake " % ( ip )
c.do_handshake()
cert = c.get_peer_certificate()
print "issuer: ",cert.get_issuer()
print "subject: ",cert.get_subject().get_components()
c.shutdown()
s.close()

3.使用openssl 的 s_client命令去获取

openssl s_client -connect 65.55.85.12:443
subject=/1.3.6.1.4.1.311.60.2.1.3=US/1.3.6.1.4.1.311.60.2.1.2=Washington/businessCategory=Private Organization/serialNumber=600413485/C=US/postalCode=98052/ST=Washington/L=Redmond/street=1 Microsoft Way/O=Microsoft Corporation/OU=Outlook Kahuna SNT-DC A May2013/CN=mail.live.com
issuer=/C=US/O=VeriSign, Inc./OU=VeriSign Trust Network/OU=Terms of use at https://www.verisign.com/rpa (c)06/CN=VeriSign Class 3 Extended Validation SSL SGC CA

s_client的其他用法可以看一下: http://blog.csdn.net/tzdjzs/article/details/28113893


4.比较

从简单性来说,使用openssl工具最为简单,但是如果要验证一组IP范围的话,又是比较麻烦

python自带的ssl库可以获取的内容比较简单,并且需要有ca证书,由于是自带的,因此可以有window以及linux下使用

pyOpenSSL库功能比较强大,在不需要验证服务器证书情况下也可以获取服务器证书的信息,但是如果在window下尝试使用,就比较头痛。


最近上网搜资料经常抽疯,无聊中就写了这个脚本。


评论关闭