python 中的 Alexa 请求验证

Alexa request validation in python

我致力于处理 Alexa 语音意图的服务。我需要验证每个请求的签名,我几乎成功了。唯一不起作用的部分是证书链的验证。

documentation 我知道:

This certificate chain is composed of, in order, (1) the Amazon signing certificate and (2) one or more additional certificates that create a chain of trust to a root certificate authority (CA) certificate.

我的代码如下所示:

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']

我不知道我做错了什么,也许有人已经实现了这个并且可以给出提示。

根据OpenSSL.crypto.X509Store documentation,

An X.509 store, being only a description, cannot be used by itself to verify a certificate. To carry out the actual verification process, see X509StoreContext.

所以你至少需要在你的商店中包含一组信任的证书,然后初始化你的商店上下文,然后你就可以做验证工作了。

您可以查看更多信息以获取实际路径(存储要信任的证书集。)

首先获得'chain.pem'所有证书的CA颁发者:

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()))

Output, for example:

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 添加到 issuerCA_store,然后对 all 执行 .verify_certificate '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 - cryptography:1.8.2 - cffi:1.10.0