Как проверить сертификат SSL в python? - PullRequest
13 голосов
/ 09 декабря 2010

Мне нужно убедиться, что сертификат был подписан моим пользовательским центром сертификации.Используя утилиты командной строки 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 является "наиболее полной" оболочкой Python для OpenSSL, но я не могу понять, как выполнить утилиту командной строки!

Ссылка на этот вопрос о том, как выполнить ту же задачу в коде на C, я смог пройти примерно половину пути. Имена переменных, которые я выбрал, те же, что и в исходном коде утилиты командной строки проверки openssl, см. 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?Стоит ли искать совершенно другую оболочку Python для OpenSSL?Как я могу выполнить эту задачу в python!?!?

Обратите внимание, что я использую сертификаты для шифрования / дешифрования файлов, поэтому меня не интересует использование однорангового сертификата на основе SSL-соединенияподтверждение (на которое уже получен ответ ), потому что у меня нет никаких соединений SSL.

Ответы [ 3 ]

5 голосов
/ 13 декабря 2010

Вы не можете сделать это с простым 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 кажется застойной (в течение последних двух лет не было закрытых проблем в системе отслеживания ошибок), и сопровождающий игнорировал мои ошибки и электронные письма с этими и некоторыми другими исправлениями ...

0 голосов
/ 10 декабря 2010

Вы можете использовать, к сожалению, недокументированный метод X509.verify, чтобы проверить, был ли сертификат подписан закрытым ключом CA.Поскольку это вызывает x509_verify OpenSSL в фоновом режиме, я уверен, что это также проверяет все параметры (например, срок действия) правильно:

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
0 голосов
/ 10 декабря 2010

Как вы сказали, OpenSSL требует подключения

M2Crypto не имеет хорошей проверки

Как насчет этой гениальной идеи:

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

Это уродливо, но работает!

...