Alexa запрашивает подтверждение в python

Я работаю над сервисом, который будет обрабатывать идеи Alexa. Мне нужно проверить подпись каждого запроса, и я почти преуспел. Единственная часть, которая не работает, - это проверка цепочки сертификатов.

Из документации Я знаю, что:

Эта цепочка сертификатов состоит из: (1) подписания Amazon сертификат и (2) один или несколько дополнительных сертификатов, которые создают цепочку доверять сертификату центра сертификации (CA).

Мой код выглядит следующим образом:

certificates = pem.parse_file("chain.pem")
store = crypto.X509Store()
for cert in certificates[:-1]:
    loaded_cert = crypto.load_certificate(crypto.FILETYPE_PEM,
                                          cert.as_bytes())
    store.add_cert(loaded_cert)

intermediate_cert = crypto.load_certificate(
    crypto.FILETYPE_PEM,
    certificates[-1].as_bytes()
)
# Create a certificate context
store_ctx = crypto.X509StoreContext(store, intermediate_cert)

# Verify the certificate
store_ctx.verify_certificate()

Я получаю следующую ошибку:

OpenSSL.crypto.X509StoreContextError: [20, 0, 'unable to get local issuer certificate']

Я не знаю, что я сделал неправильно, возможно, есть кто-то, кто уже реализовал это и может отказаться от намека.

Ответы

Ответ 1

Сначала и один раз получите сертификат CA для сертификата all в 'chain.pem':

for cert in pem.parse_file("chain.pem"):
    CA_cert = crypto.load_certificate(crypto.FILETYPE_PEM, cert.as_bytes())
    print('CA_cert:\nissuer :{}\nsubject:{}'.
        format(CA_cert.get_subject(), CA_cert.get_issuer()))

Вывод, например:

CA_cert:
issuer :<X509Name object '/C=US/O=thawte, Inc./OU=Certification Services Division/OU=(c) 2006 thawte, Inc. - For authorized use only/CN=thawte Primary Root CA'>
subject:<X509Name object '/C=US/O=thawte, Inc./OU=Certification Services Division/OU=(c) 2006 thawte, Inc. - For authorized use only/CN=thawte Primary Root CA'>

Этот показанный пример сертификата - это самоподписанный сертификат.


Добавьте all показанный эмитент к CA_store, затем выполните .verify_certificate для all сертификата в 'chain.pem'.

CA_store = crypto.X509Store()
for _pem in ['issuer_1.pem', 'issuer_2.pem']:
    for cert in pem.parse_file(_pem):
        CA_store.add_cert(
            crypto.load_certificate(crypto.FILETYPE_PEM, cert.as_bytes())
        )

for cert in pem.parse_file("chain.pem"):
    try:
        crypto.X509StoreContext(CA_store,
                                crypto.load_certificate(crypto.FILETYPE_PEM, cert.as_bytes())
                                ).verify_certificate()
    except X509StoreContextError as exp:
        cert = exp.certificate
        print('X509StoreContextError:{}\ncertificate\n\tissuer :{}\n\tsubject:{}'.
            format(exp.args, cert.get_issuer(), cert.get_subject()))

Протестировано с помощью Python: 3.4.2 - OpenSSL: 17.0.0 - криптография: 1.8.2 - cffi: 1.10.0

Ответ 2

Согласно OpenSSL.crypto.X509Установить документацию,

Хранилище X.509, являющееся только описанием, само по себе не может использоваться для проверки сертификата. Чтобы выполнить фактический процесс проверки, см. X509StoreContext.

Итак, вам нужно хотя бы включить в свой магазин набор сертификатов, чтобы доверять первым, а затем инициализировать файл storecontext, после чего вы можете выполнить задание проверки.

Вы можете увидеть дополнительную информацию здесь, чтобы получить фактический путь (на котором хранится набор доверенных сертификатов.)