example - Solicitud de validación de Alexa en python
ask sdk python (2)
Trabajo en un servicio que manejará los intentos de voz de Alexa. Necesito verificar la firma de cada solicitud y casi lo logro. La única parte que no está funcionando es la validación de la cadena de certificados.
De la documentation sé que:
Esta cadena de certificados se compone, en orden, de (1) el certificado de firma de Amazon y (2) uno o más certificados adicionales que crean una cadena de confianza para un certificado de autoridad de certificación raíz (CA).
Mi código se ve así:
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()
Recibo el siguiente error:
OpenSSL.crypto.X509StoreContextError: [20, 0, ''unable to get local issuer certificate'']
No sé qué hice mal, tal vez haya alguien que ya haya implementado esto y pueda dejar una pista.
De acuerdo con la documentación de OpenSSL.crypto.X509Store ,
Una tienda X.509, que es solo una descripción, no se puede usar sola para verificar un certificado. Para llevar a cabo el proceso de verificación real, consulte X509StoreContext.
Por lo tanto, necesita al menos incluir en su tienda un conjunto de certificados en los que confiar primero, luego inicializar el almacenamiento y luego hacer el trabajo de verificación.
Puede ver más información here para obtener la ruta real (en la que se almacena el conjunto de certificados de confianza).
Primero y una vez obtenga el Emisor de CA para todos los certificados en ''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()))
Salida , por ejemplo:
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''>
Este ejemplo de certificado es un certificado autofirmado .
Agregue todos los emisores que se muestran a CA_store
, luego haga .verify_certificate
para todos los certificados en ''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()))
Probado con Python: 3.4.2 - OpenSSL: 17.0.0 - criptografía: 1.8.2 - cffi: 1.10.0