Moh*_*Moh 2 python linux ssl openssl
我正在尝试使用主机名将主题字段捕获为字符串。像这样:
/C=US/ST=California/L=Mountain View/O=Google LLC/CN=*.google.com
Run Code Online (Sandbox Code Playgroud)
使用以下命令可以获得相同的输出
echo -n | openssl s_client -connect google.com:443 2>/dev/null | grep subject
subject=/C=US/ST=California/L=Mountain View/O=Google LLC/CN=*.google.com
Run Code Online (Sandbox Code Playgroud)
尝试了一些 subprocess 模块来获取上述输出,但最终落在 OpenSSL 模块上来帮助我,因为我不太熟悉 Subprocess 模块。使用 OpenSSL,我能够获得所需的输出,但它会将其作为 X509Name 对象返回:
import socket, ssl
import OpenSSL
hostname = "google.com"
cert = ssl.get_server_certificate((hostname, 443))
x509 = OpenSSL.crypto.load_certificate(OpenSSL.crypto.FILETYPE_PEM, cert)
print(x509.get_subject())
<X509Name object '/C=US/ST=California/L=Mountain View/O=Google LLC/CN=*.google.com'>
Run Code Online (Sandbox Code Playgroud)
我希望它以字符串形式返回。这可以实现吗?
检查[pyOpenSSL]: crypto - X509Name 对象( get_components ) 了解更多详细信息。
经过一些处理,这是可能的。专有名称字符串是各个组成字符串的串联,其中每个组成字符串的形式为./name=value
例子:
Run Code Online (Sandbox Code Playgroud)>>> import ssl >>> import OpenSSL >>> >>> pem = ssl.get_server_certificate(("google.com", 443)) >>> cert_x509 = OpenSSL.crypto.load_certificate(OpenSSL.crypto.FILETYPE_PEM, cert) >>> >>> subject = cert_x509.get_subject() >>> subject <X509Name object '/C=US/ST=California/L=Mountain View/O=Google LLC/CN=*.google.com'> >>> >>> subject_str = "".join("/{:s}={:s}".format(name.decode(), value.decode()) for name, value in subject.get_components()) >>> subject_str '/C=US/ST=California/L=Mountain View/O=Google LLC/CN=*.google.com'
获取证书数据的方法有多种,这是另一种:[SO]: How can I Decode a SSLcertificate using python? (@CristiFati 的回答)。