I am trying to get Certificate issuer information (Common Name), but the code in the link doesn’t work with some URLs.
How can i get Certificate issuer information in python?
import ssl, socket hostname = 'google.com' ctx = ssl.create_default_context() s = ctx.wrap_socket(socket.socket(), server_hostname=hostname) s.connect((hostname, 443)) cert = s.getpeercert() subject = dict(x[0] for x in cert['subject']) issued_to = subject['commonName'] >>> issued_to u'*.google.com'
For example, I tried hostname “cds.ca”, it says
ssl.SSLError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:661)
but I could still get the Common name using Internet Explorer (*.cds.ca)
So I think I should use my own certificate(.cer) instead of using getpeercert(), then how should I change that line?
Or, is there any other way to achieve CN with my own certificate file?
Answers:
Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.
Method 1
If you just want to get the CN or other certificate details no matter if certificate validation succeeds or not, you have to disable the verification. Unfortunately a simple sock.getpeercert() will by design only return an empty dictionary if certificate validation is disabled. That’s why one has to use sock.getpeercert(True) to get the binary representation of the certificate and extract the CN using OpenSSL.crypto from it:
import socket
import ssl
import OpenSSL.crypto as crypto
dst = ('cds.ca',443)
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(dst)
# upgrade the socket to SSL without checking the certificate
# !!!! don't transfer any sensitive data over this socket !!!!
ctx = ssl.create_default_context()
ctx.check_hostname = False
ctx.verify_mode = ssl.CERT_NONE
s = ctx.wrap_socket(s, server_hostname=dst[0])
# get certificate
cert_bin = s.getpeercert(True)
x509 = crypto.load_certificate(crypto.FILETYPE_ASN1,cert_bin)
print("CN=" + x509.get_subject().CN)
All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0