如何在 python 中验证 SSL 证书?

发布于 2024-10-07 12:18:19 字数 2002 浏览 4 评论 0原文

我需要验证证书是否由我的自定义 CA 签名。使用 OpenSSL 命令行实用程序这很容易做到:

# Custom CA file: ca-cert.pem
# Cert signed by above CA: bob.cert
$ openssl verify -CAfile test-ca-cert.pem bob.cert
bob.cert: OK

但我需要在 Python 中做同样的事情,而且我真的不想调用命令行实用程序。据我所知,M2Crypto 是 OpenSSL 的“最完整”Python 包装器,但我不知道如何完成命令行实用程序的功能!

参考这个问题了解如何在 C 代码中完成相同的任务,我'已经能够完成一半了。 我选择的变量名称与 openssl verify 命令行实用程序的源代码中使用的变量名称相同,请参阅 openssl-xxx/apps/verify.c

import M2Crypto as m2
# Load the certificates
cacert = m2.X509.load_cert('test-ca-cert.pem')   # Create cert object from CA cert file
bobcert = m2.X509.load_cert('bob.cert')     # Create cert object from Bob's cert file
cert_ctx = m2.X509.X509_Store()             # Step 1 from referenced C code steps
csc = m2.X509.X509_Store_Context(cert_ctx)  # Step 2 & 5
cert_ctx.add_cert(cacert)                   # Step 3
cert_ctx.add_cert(bobcert)                  # ditto
# Skip step 4 (no CRLs to add)
# Step 5 is combined with step 2...I think. (X509_STORE_CTX_init: Python creates and 
#   initialises an object in the same step)
# Skip step 6? (can't find anything corresponding to 
#   X509_STORE_CTX_set_purpose, not sure if we need to anyway???)
# 
# It all falls apart at this point, as steps 7 and 8 don't have any corresponding
# functions in M2Crypto -- I even grepped the entire source code of M2Crypto, and
# neither of the following functions are present in it:
# Step 7: X509_STORE_CTX_set_cert - Tell the context which certificate to validate.
# Step 8: X509_verify_cert - Finally, validate it

所以我已经完成一半了,但我似乎无法真正完成验证!我错过了什么吗?我还应该使用 M2Crypto 的其他功能吗?我应该寻找一个完全不同的 OpenSSL python 包装器吗?我怎样才能在Python中完成这个任务!?!?

请注意,我正在使用证书来加密/解密文件,因此我对使用基于 SSL 连接的对等证书验证不感兴趣(它具有 已经得到答复),因为我没有任何 SSL 连接。

I need to verify that a certificate was signed by my custom CA. Using OpenSSL command-line utilities this is easy to do:

# Custom CA file: ca-cert.pem
# Cert signed by above CA: bob.cert
$ openssl verify -CAfile test-ca-cert.pem bob.cert
bob.cert: OK

But I need to do the same thing in Python, and I really don't want to call out to command-line utilities. As far as I'm aware, M2Crypto is the "most complete" python wrapper for OpenSSL, but I can't figure out how to accomplish what the command-line utility does!

Referencing this question for how to accomplish this same task in C code, I've been able to get about half-way. The variable names I chose are the same ones used in the source code for the openssl verify command-line utility, see openssl-xxx/apps/verify.c.

import M2Crypto as m2
# Load the certificates
cacert = m2.X509.load_cert('test-ca-cert.pem')   # Create cert object from CA cert file
bobcert = m2.X509.load_cert('bob.cert')     # Create cert object from Bob's cert file
cert_ctx = m2.X509.X509_Store()             # Step 1 from referenced C code steps
csc = m2.X509.X509_Store_Context(cert_ctx)  # Step 2 & 5
cert_ctx.add_cert(cacert)                   # Step 3
cert_ctx.add_cert(bobcert)                  # ditto
# Skip step 4 (no CRLs to add)
# Step 5 is combined with step 2...I think. (X509_STORE_CTX_init: Python creates and 
#   initialises an object in the same step)
# Skip step 6? (can't find anything corresponding to 
#   X509_STORE_CTX_set_purpose, not sure if we need to anyway???)
# 
# It all falls apart at this point, as steps 7 and 8 don't have any corresponding
# functions in M2Crypto -- I even grepped the entire source code of M2Crypto, and
# neither of the following functions are present in it:
# Step 7: X509_STORE_CTX_set_cert - Tell the context which certificate to validate.
# Step 8: X509_verify_cert - Finally, validate it

So I'm halfway there, but I can't seem to actually get the validation done! Am I missing something? Is there some other function I should be using from M2Crypto? Should I be looking for a completely different python wrapper of OpenSSL? How can I accomplish this task in python!?!?

Note that I'm using certificates to encrypt/decrypt FILES, so I'm not interested in using the SSL-connection-based peer certificate verification (which has already been answered), because I don't have any SSL connections going.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

空心空情空意 2024-10-14 12:18:19

您无法使用普通的 M2Crypto 来执行此操作,因为它没有包装一些所需的功能。好消息是,如果您安装了 SWIG,您可以自己包装它们并与 M2Crypto 代码一起使用。我前段时间为自己制作了一个带有一些额外功能的模块,并决定现在发布它,因为它进行了这种验证。您可以在这里查看:https://github.com/abbot/m2ext。这是如何使用此模块验证证书的示例:

import sys
from m2ext import SSL
from M2Crypto import X509

print "Validating certificate %s using CApath %s" % (sys.argv[1], sys.argv[2])
cert = X509.load_cert(sys.argv[1])
ctx = SSL.Context()
ctx.load_verify_locations(capath=sys.argv[2])
if ctx.validate_certificate(cert):
    print "valid"
else:
    print "invalid"

不幸的是,M2Crypto 开发似乎停滞不前(过去两年错误跟踪器中没有解决问题),并且维护者忽略了我的错误和电子邮件以及这些补丁和其他一些补丁。 。

You can't do this with plain M2Crypto, since it does not wrap some of the required functions. Good news is if you have SWIG installed you can wrap those yourself and use with M2Crypto code. I've made a module with some extra functions for myself some time ago, and decided to publish it now, since it does this kind of validation. You can check it here: https://github.com/abbot/m2ext. This is an example how to validate a certificate using this module:

import sys
from m2ext import SSL
from M2Crypto import X509

print "Validating certificate %s using CApath %s" % (sys.argv[1], sys.argv[2])
cert = X509.load_cert(sys.argv[1])
ctx = SSL.Context()
ctx.load_verify_locations(capath=sys.argv[2])
if ctx.validate_certificate(cert):
    print "valid"
else:
    print "invalid"

Unfortunately M2Crypto development seems to be stagnant (no closed issues in bug tracker for the last two years) and the maintainer was ignoring my bugs and emails with these and some other patches...

Hello爱情风 2024-10-14 12:18:19

使用这个命令:
/Applications/Python\ 3.9/Install\ Certificates.command

不要更改空格,只需确保替换为您的 python 版本

Use this command:
/Applications/Python\ 3.9/Install\ Certificates.command

do not alter the spaces, just be sure to replace with your version of python

像你 2024-10-14 12:18:19

您可以使用不幸的是未记录的 X509.verify 方法检查证书是否是用 CA 的私钥签名的。由于这会在后台调用 OpenSSL 的 x509_verify,因此我确信这也会正确检查所有参数(例如过期时间):

from M2Crypto X509

cert = X509.load_cert("certificate-filename")

caCertificate = X509.load_cert("trusted-ca-filename")
caPublic = caCertificate.get_pubkey()

if cert.verify(caPublic) == 1:
     # Certificate is okay!
else:
     # not okay

You can use the unfortunately undocumented X509.verify method to check whether the certificate was signed with the CA's private key. As this calls OpenSSL's x509_verify in the background, I'm sure this also checks all parameters (like expiration) correctly:

from M2Crypto X509

cert = X509.load_cert("certificate-filename")

caCertificate = X509.load_cert("trusted-ca-filename")
caPublic = caCertificate.get_pubkey()

if cert.verify(caPublic) == 1:
     # Certificate is okay!
else:
     # not okay
蓝礼 2024-10-14 12:18:19

就像你说的,
OpenSSL 需要连接

M2Crypto 没有良好的验证

这个巧妙的想法怎么样:

import os 
os.system('openssl verify -CAfile ../ca-cert.pem bob.cert')

它丑陋,但它有效!

Like you said,
OpenSSL requires connection

M2Crypto doesn't have good verification

How about this ingenious idea:

import os 
os.system('openssl verify -CAfile ../ca-cert.pem bob.cert')

Its ugly, but it works!

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文