如何在 Python 中将 X509Name 对象转换为字符串

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)

我希望它以字符串形式返回。这可以实现吗?

Cri*_*ati 6

检查[pyOpenSSL]: crypto - X509Name 对象( get_components ) 了解更多详细信息。

经过一些处理,这是可能的。专有名称字符串是各个组成字符串的串联,其中每个组成字符串的形式为./name=value

例子

>>> 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'
Run Code Online (Sandbox Code Playgroud)

获取证书数据的方法有多种,这是另一种:[SO]: How can I Decode a SSLcertificate using python? (@CristiFati 的回答)