Python getpeercert获取ssl证书信息

我想获得一个ssl证书的信息从一个域名。   
我用下面的代码连接反应。


import ssl
import socket

sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.settimeout(1)
wrappedSocket = ssl.wrap_socket(sock)
try:
wrappedSocket.connect(('www.google.com', 443))
except:
response = False
else:
der_cert = wrappedSocket.getpeercert(False)
der_cert_bin = wrappedSocket.getpeercert(True)
print(der_cert)
print(der_cert_bin)
pem_cert = ssl.DER_cert_to_PEM_cert(wrappedSocket.getpeercert(True))
print(pem_cert)
wrappedSocket.close()

输出如下


{}
b'0\x82\x04v0\x82\x03^\xa0\x03\x02\x01\x02\x02\x08\x19\xab\x97n|\x13q\xc20\r\x06\t*\x86H\x86\xf7\r\x01\x01\x05\x05\x000I1\x0b0\t\x06\x03U\x04\x06\x13\x02US1\x130\x11\x06\x03U\x04\n\x13\nGoogle Inc1%0#\x06\x03U\x04\x03\x13\x1cGoogle Internet Authority G20\x1e\x17\r150618085256Z\x17\r150916000000Z0h1\x0b0\t\x06\x03U\x04\x06\x13\x02US1\x130\x11\x06\x03U\x04\x08\x0c\nCalifornia1\x160\x14\x06\x03U\x04\x07\x0c\rMountain View1\x130\x11\x06\x03U\x04\n\x0c\nGoogle Inc1\x170\x15\x06\x03U\x04\x03\x0c\x0ewww.google.com0\x82\x01"0\r\x06\t*\x86H\x86\xf7\r\x01\x01\x01\x05\x00\x03\x82\x01\x0f\x000\x82\x01\n\x02\x82\x01\x01\x00\xca\xa9\\\x03\xb4\x07g\xb4\x87b\xeb\xf6\xd3\xc7,\xeb\ta\x07j\xaa\xab\xf80,\xd3\xbc9:p%-D\xe9\x94\xb4\xac\x12\x84P$\nUV\x15\xe3\r\xb8,\xb1[<\xc6\xf6\x8c\xf1\x8f\xbb\xfc\xc3\xec\x9f!\xee\xc4\xc9\xa4\xfc/\x8b\x02\xeb\xce\xa5\xc5\xb8\xc9[N3\xeet\x91\\\xf7\x1e\xd6\xf7|\xde\xd0\xd1\x11\xeal\xc5\r\x8c\x0b\x8c\xb4/\x8a\xc1\xbb>\x1e\xa1,\x1d01\xc1k\xdc\xca\x9b\xebH-\xa9\x19\xfc\xff\x81<\xb8\xefm\xf0\x8b\x91\x02\xf9\xe9\x07(\'\xed\xe6\x98|4\xe7\xef\x9c\xea;\x13\xcf1\xaa\xe3}\x96\x95?\xef]\x1f\x86\xc5,\xed\xbf K9j \xaad6\xf2\x10G\xcdY\x9c\xd0\x89\xeb\xc1\x11\xc3\xa5\xd5\xac\x17)\xf7\xff\x01\x9d\xa5\xd1\x1aN\xc1[\xa8\xd3L\xb1\x8b\xa7`\xac\x12\xc2\xcf\xc6RF\x88\x02\x8f4\x1ak1\xad\xeeom}\x1d"\xdc\x84~\xe2\x9d\xfe\xf2\xd9\r\xa0JH\xd6>3.\xb6J\xd4\xde\xa1X\xd5\x9c\x9b\xc3\xb8\xab\x02\x03\x01\x00\x01\xa3\x82\x01A0\x82\x01=0\x1d\x06\x03U\x1d%\x04\x160\x14\x06\x08+\x06\x01\x05\x05\x07\x03\x01\x06\x08+\x06\x01\x05\x05\x07\x03\x020\x19\x06\x03U\x1d\x11\x04\x120\x10\x82\x0ewww.google.com0h\x06\x08+\x06\x01\x05\x05\x07\x01\x01\x04\\0Z0+\x06\x08+\x06\x01\x05\x05\x070\x02\x86\x1fhttp://pki.google.com/GIAG2.crt0+\x06\x08+\x06\x01\x05\x05\x070\x01\x86\x1fhttp://clients1.google.com/ocsp0\x1d\x06\x03U\x1d\x0e\x04\x16\x04\x14\x14\xd9\xa1\xe1\x91@$\xf3\x03\xf1\xd0\xfaIg\x11R\xe4 hT0\x0c\x06\x03U\x1d\x13\x01\x01\xff\x04\x020\x000\x1f\x06\x03U\x1d#\x04\x180\x16\x80\x14J\xdd\x06\x16\x1b\xbc\xf6h\xb5v\xf5\x81\xb6\xbbb\x1a\xbaZ\x81/0\x17\x06\x03U\x1d \x04\x100\x0e0\x0c\x06\n+\x06\x01\x04\x01\xd6y\x02\x05\x0100\x06\x03U\x1d\x1f\x04)0\'0%\xa0#\xa0!\x86\x1fhttp://pki.google.com/GIAG2.crl0\r\x06\t*\x86H\x86\xf7\r\x01\x01\x05\x05\x00\x03\x82\x01\x01\x00q]\x07r\x9e\x9b\xc1\xb0\xe7\xb7aV\xd9M%\xdf\xa4\x9c\xfd\xbc\x10\xc1,!8\xc2\xe2\x81f\x87\xf6\xc9\x95\x14\xe8\x99@\xb8\x97Xh\x9d\\\xd6\xe9ZVDQ\\o\x9aXD\xfd\x15\xead<@U!\xc2\x84\x14&\x91\xdb\x85/Ek\xdc\x80\xc4\xf4\xd9\xe0\x00\xca\xbb=\x0f\xcd5\xd0.\xbb\xd3 4\xab\xfa\xec\xe9]\x040\xfc\xe8\xea\xee\xe6*\xe8\xf5\x8e\xf8\x91\x0b\xba\xf92\x02\xe6\x04

解决方案:
  如果参数binary_form是假的,证书收到同行,该方法返回一个dict实例。如果证书不验证,关键字是空的。
  如果证书验证,它返回一个dict和几个键,其中主题(校长的证书发布)和发行人(校长签发证书)。
  如果证书包含主题选择扩展名的实例(见RFC 3280),还会有subjectAltName密钥字典。         
  如果你想验证您必须通过cert_reqs = ssl证书。CERT_REQUIRED ssl。
  
  wrap_socket(下面定义):      


ssl.wrap_socket(sock, keyfile=None, certfile=None, server_side=False, cert_reqs=CERT_NONE, ssl_version={see docs}, ca_certs=None, do_handshake_on_connect=True, suppress_ragged_eofs=True, ciphers=None).

  如你所见默认情况下通过CERT_NONE,没有验证证书,因此你得到一个空的字典

原文:

The documentation is pretty clear:

If the parameter binary_form is False, and a certificate was received from the peer, this method returns a dict instance. If the certificate was not validated, the dict is empty. If the certificate was validated, it returns a dict with several keys, amongst them subject (the principal for which the certificate was issued) and issuer (the principal issuing the certificate). If a certificate contains an instance of the Subject Alternative Name extension (see RFC 3280), there will also be a subjectAltName key in the dictionary.

If you want to validate the certificate you must pass cert_reqs=ssl.CERT_REQUIRED to ssl.wrap_socket(here's the definition):

ssl.wrap_socket(sock, keyfile=None, certfile=None, server_side=False, cert_reqs=CERT_NONE, ssl_version={see docs}, ca_certs=None, do_handshake_on_connect=True, suppress_ragged_eofs=True, ciphers=None).

As you see by default it passes CERT_NONE, which doesn't validate the peer certificate, therefore you get an empty dict.

发表评论

电子邮件地址不会被公开。 必填项已用*标注