Kre*_*dns 10 python ssl certificate x509 python-2.7
我正在尝试确定SSL证书是否是自签名的。目前,我有以下代码比较发行方CN和主题CN,如果它们相同,则将结果标记为自签名。
with open(cert_file, "r") as f:
x509 = OpenSSL.crypto.load_certificate(OpenSSL.crypto.FILETYPE_PEM, f.read())
result = {
'subject': dict(x509.get_subject().get_components()),
'issuer': dict(x509.get_issuer().get_components()),
'serialNumber': x509.get_serial_number(),
'version': x509.get_version(),
'notBefore': datetime.strptime(x509.get_notBefore(), '%Y%m%d%H%M%SZ'),
'notAfter': datetime.strptime(x509.get_notAfter(), '%Y%m%d%H%M%SZ'),
}
extensions = (x509.get_extension(i) for i in range(x509.get_extension_count()))
extension_data = {e.get_short_name(): str(e) for e in extensions}
result.update(extension_data)
if result['issuer']['CN'] == result['subject']['CN']:
result.update({'self-signed': True})
else:
result.update({'self-signed': False})
Run Code Online (Sandbox Code Playgroud)
这种比较非常简单,但是在很多情况下都可以使用。我不是要验证SSL证书或重新实现OpenSSL。我该如何做得更好,大约95%可以确定证书是否是自签名的?
我的一个要求是,我想在Python中执行此操作,而不要调用其他进程或使用Shell命令。
主题和发行者名称匹配,扩展值意味着它是自签名的。
/* Return 1 is a certificate is self signed */
static int cert_self_signed(X509 *x)
{
X509_check_purpose(x, -1, 0);
if (x->ex_flags & EXFLAG_SS)
return 1;
else
return 0;
}
Run Code Online (Sandbox Code Playgroud)
以及设置的代码EXFLAG_SS:
/* Does subject name match issuer ? */
if (!X509_NAME_cmp(X509_get_subject_name(x), X509_get_issuer_name(x))) {
x->ex_flags |= EXFLAG_SI;
/* If SKID matches AKID also indicate self signed */
if (X509_check_akid(x, x->akid) == X509_V_OK &&
!ku_reject(x, KU_KEY_CERT_SIGN))
x->ex_flags |= EXFLAG_SS;
}
Run Code Online (Sandbox Code Playgroud)
所以基本上要检查三件事:
KU_KEY_CERT_SIGN设置了位的密钥用法扩展您已经在比较主题名称和发行人名称。接下来要做的重要事情是比较 SKID 和 AKID。在粗略地看一下 pyopenssl 后,它似乎没有提供一种检查方法,因此如果您想要一个纯 Python 解决方案,您可能必须扩展该库。但是,即使您拥有的代码也可能在您说要覆盖的 95% 的情况下覆盖您。
| 归档时间: |
|
| 查看次数: |
547 次 |
| 最近记录: |