Reach

Grow

Manage

Automate

Reach

Grow

Manage

Automate

S/MIME Parte 4: Recopilación de Claves Públicas de Destinatarios de la Manera Fácil – con los Webhooks de Relé Entrante de SparkPost

Correo electrónico

1 min read

S/MIME Parte 4: Recopilación de Claves Públicas de Destinatarios de la Manera Fácil – con los Webhooks de Relé Entrante de SparkPost

Correo electrónico

1 min read

S/MIME Parte 4: Recopilación de Claves Públicas de Destinatarios de la Manera Fácil – con los Webhooks de Relé Entrante de SparkPost

En esta serie, hemos visto que incluir una firma S/MIME es bastante sencillo. Enviar correo electrónico cifrado con S/MIME es más complejo porque necesitas obtener las claves públicas de los destinatarios. Es una cosa cuando usas un cliente de correo para humanos como Thunderbird, pero ¿cómo puede funcionar eso con flujos de correo electrónico generados por aplicaciones?

En parte 1, tuvimos un recorrido rápido por S/MIME, observando la firma y el cifrado de nuestros flujos de mensajes a través de una variedad de clientes de correo. Parte 2 nos llevó a través de una herramienta de línea de comandos simple para firmar y cifrar correos electrónicos, luego enviarlos a través de SparkPost. Parte 3 mostró cómo inyectar flujos de correo seguros en plataformas locales como Port25 PowerMTA y Momentum.

En esta serie, hemos visto que incluir una firma S/MIME es bastante sencillo. Enviar correo cifrado con S/MIME es más complejo porque necesitas obtener las claves públicas de los destinatarios. Es una cosa cuando estás usando un cliente de correo para humanos como Thunderbird, pero ¿cómo puede eso funcionar con flujos de correo generados por apps?

Pero espera, hay otra forma de llegar a Mordor para obtener esas claves. Tu servicio puede invitar a tus clientes (vía correo electrónico, por supuesto) a enviarte de vuelta un correo firmado a una dirección de servicio al cliente conocida. Usando los poderes mágicos de los webhooks de SparkPost Inbound Relay, extraeremos y almacenaremos esa clave pública para que la uses.

Podemos resumir esto en un caso de uso simple:

  • Como receptor de mensajes, proporciono a tu servicio mi firma de correo electrónico personal a través de correo electrónico, de modo que en el futuro, los correos puedan serme enviados en forma cifrada con S/MIME.

A partir de esto, derivemos algunos requisitos más detallados:




  • Necesitamos un servicio de correo electrónico entrante siempre disponible y confiable para recibir esos correos firmados.

  • No debería haber requisitos especiales en el formato del correo, aparte de que debe llevar una firma S/MIME.

  • Dado que cualquiera puede intentar enviar un correo a este servicio, debería diseñarse de manera defensiva, por ejemplo, para rechazar mensajes "falsificados" de actores malintencionados. Habrá necesidad de varias capas de verificación.

  • Si todo está bien, el servicio almacenará el certificado en un archivo, utilizando el conocido formato de texto plano Privacy-Enhanced Mail (PEM).

Existen algunos requisitos no funcionales:

  • Los servicios de webhook de máquina a máquina pueden ser difíciles de ver solo por las respuestas a lo que está sucediendo por dentro. El servicio debería proporcionar registros extensos a nivel de aplicación legibles por humanos. En particular, el análisis y verificación de certificados debe ser registrado.

  • Añadimos casos de prueba para los internos de la app, utilizando el agradable marco de trabajo Pytest, y ejecutamos esas pruebas automáticamente al realizar check-in usando la integración de Travis CI con GitHub.

¡OK, comencemos!

1. Resumen de la solución

Aquí está cómo se verá la solución general.

2. Instalación, configuración y puesta en marcha de la aplicación web

Empezaremos con esta parte, para que la tengamos completamente probada antes de dirigirnos a los webhooks de relé de entrada.

La aplicación web está incluida en el mismo proyecto de GitHub que las partes 1 – 3, así que si has seguido esas partes, ya la tienes. Aquí están las novedades:

  • Programa readSMIMEsig.py: lee un correo electrónico y extrae los certificados intermedios y de usuario.

  • Programa webapp.py: aplicación web compatible con Flask para usar con SparkPost Inbound Relay Webhooks.

  • webapp.ini: archivo de configuración para lo anterior. Un archivo de configuración permite que los mismos valores se pasen fácilmente tanto a las aplicaciones de línea de comandos como a las web.




Necesitas asegurarte de que tu host tenga el número de puerto TCP correcto abierto a solicitudes entrantes del exterior para que SparkPost pueda enviar mensajes a tu aplicación. Si estás alojado en AWS EC2, por ejemplo, necesitarás configurar el Security Group de tu instancia.

Las instrucciones para configurar y comenzar la aplicación web se dan aquí– es bastante fácil. Para comprobar que tu aplicación esté funcionando y sea accesible desde el exterior, puedes enviar solicitudes (en blanco) desde otro host utilizando curl, por ejemplo:

curl -X POST https://app.trymsys.net:8855/

Deberías ver una respuesta como:

{"message":"Content-Type desconocido en los encabezados de la petición"}

Esto es algo bueno: ¡tu aplicación está funcionando!

En webapp.log en tu host, verás una salida similar a esta:

2019-01-15 00:11:07,575,root,INFO,Request from 38.96.5.10,scheme=https,path=/ 2019-01-15 00:11:07,575,root,INFO,| len(headers)=3,len(body)=None 2019-01-15 00:11:07,575,root,INFO,| Content-Type desconocido: None

Para ayudarte a jugar con datos reales en tu aplicación rápidamente, puedes importar esta petición de Postman específica desde el repositorio del proyecto. Esto simula lo que hará tu cuenta de SparkPost, es decir, envía un POST https que contiene un correo electrónico con un certificado específico y válido (perteneciente a una cuenta de prueba mía) a tu aplicación.

Solo necesitas cambiar la dirección de destino en la petición (en el cuadro gris anterior) para que coincida con tu instalación. Si cambiaste el valor del token en webapp.ini, ajusta el valor del encabezado en Postman para que coincida.

Si tu aplicación está funcionando, verás una respuesta “200 OK” de regreso en Postman. El archivo webapp.log de tu host contendrá una salida como esta:

2019-01-15 00:11:48,554,root,INFO,Request from 38.96.5.10,scheme=https,path=/ 2019-01-15 00:11:48,554,root,INFO,| len(headers)=10,len(body)=14778 2019-01-15 00:11:48,555,root,INFO,| msg_from=bob.lumreeker@gmail.com,rcpt_to=secureme@inbound.thetucks.com,len(email_rfc822)=9223 2019-01-15 00:11:48,599,root,INFO,| from=bob.lumreeker@gmail.com,DKIM passed 2019-01-15 00:11:48,600,root,INFO,| content-type=multipart/signed; protocol="application/pkcs7-signature"; micalg=sha-256; boundary="------------ms010908020707040304020406",description=None 2019-01-15 00:11:48,600,root,INFO,| content-type=text/plain; charset=utf-8; format=flowed,description=None 2019-01-15 00:11:48,600,root,INFO,| content-type=application/pkcs7-signature; name="smime.p7s",description=Firma criptográfica S/MIME 2019-01-15 00:11:48,600,root,INFO,| filename=smime.p7s,bytes=3998 2019-01-15 00:11:48,601,root,INFO,| Certificate: subject email_address=['bob.lumreeker@gmail.com'],not_valid_before=2018-10-03 00:00:00,not_valid_after=2019-10-03 23:59:59,hash_algorithm=sha256,key_size=2048 bytes, issuer={'countryName': 'GB', 'stateOrProvinceName': 'Greater Manchester', 'localityName': 'Salford', 'organizationName': 'COMODO CA Limited', 'commonName': 'COMODO RSA Client Authentication and Secure Email CA'} 2019-01-15 00:11:48,602,root,INFO,| Certificate: subject email_address=[],not_valid_before=2013-01-10 00:00:00,not_valid_after=2028-01-09 23:59:59,hash_algorithm=sha384,key_size=2048 bytes, issuer={'countryName': 'GB', 'stateOrProvinceName': 'Greater Manchester', 'localityName': 'Salford', 'organizationName': 'COMODO CA Limited', 'commonName': 'COMODO RSA Certification Authority'} 2019-01-15 00:11:48,616,root,INFO,| archivo escrito ./bob.lumreeker@gmail.com.crt,bytes=1870,ok=True

Para una verificación rápida, busca la última línea: si dice “archivo escrito”, entonces estás bien. El resto de esto muestra el proceso de verificación de DKIM y validación de certificados.

Empezaremos con esta parte, para que la tengamos completamente probada antes de dirigirnos a los webhooks de relé de entrada.

La aplicación web está incluida en el mismo proyecto de GitHub que las partes 1 – 3, así que si has seguido esas partes, ya la tienes. Aquí están las novedades:

  • Programa readSMIMEsig.py: lee un correo electrónico y extrae los certificados intermedios y de usuario.

  • Programa webapp.py: aplicación web compatible con Flask para usar con SparkPost Inbound Relay Webhooks.

  • webapp.ini: archivo de configuración para lo anterior. Un archivo de configuración permite que los mismos valores se pasen fácilmente tanto a las aplicaciones de línea de comandos como a las web.




Necesitas asegurarte de que tu host tenga el número de puerto TCP correcto abierto a solicitudes entrantes del exterior para que SparkPost pueda enviar mensajes a tu aplicación. Si estás alojado en AWS EC2, por ejemplo, necesitarás configurar el Security Group de tu instancia.

Las instrucciones para configurar y comenzar la aplicación web se dan aquí– es bastante fácil. Para comprobar que tu aplicación esté funcionando y sea accesible desde el exterior, puedes enviar solicitudes (en blanco) desde otro host utilizando curl, por ejemplo:

curl -X POST https://app.trymsys.net:8855/

Deberías ver una respuesta como:

{"message":"Content-Type desconocido en los encabezados de la petición"}

Esto es algo bueno: ¡tu aplicación está funcionando!

En webapp.log en tu host, verás una salida similar a esta:

2019-01-15 00:11:07,575,root,INFO,Request from 38.96.5.10,scheme=https,path=/ 2019-01-15 00:11:07,575,root,INFO,| len(headers)=3,len(body)=None 2019-01-15 00:11:07,575,root,INFO,| Content-Type desconocido: None

Para ayudarte a jugar con datos reales en tu aplicación rápidamente, puedes importar esta petición de Postman específica desde el repositorio del proyecto. Esto simula lo que hará tu cuenta de SparkPost, es decir, envía un POST https que contiene un correo electrónico con un certificado específico y válido (perteneciente a una cuenta de prueba mía) a tu aplicación.

Solo necesitas cambiar la dirección de destino en la petición (en el cuadro gris anterior) para que coincida con tu instalación. Si cambiaste el valor del token en webapp.ini, ajusta el valor del encabezado en Postman para que coincida.

Si tu aplicación está funcionando, verás una respuesta “200 OK” de regreso en Postman. El archivo webapp.log de tu host contendrá una salida como esta:

2019-01-15 00:11:48,554,root,INFO,Request from 38.96.5.10,scheme=https,path=/ 2019-01-15 00:11:48,554,root,INFO,| len(headers)=10,len(body)=14778 2019-01-15 00:11:48,555,root,INFO,| msg_from=bob.lumreeker@gmail.com,rcpt_to=secureme@inbound.thetucks.com,len(email_rfc822)=9223 2019-01-15 00:11:48,599,root,INFO,| from=bob.lumreeker@gmail.com,DKIM passed 2019-01-15 00:11:48,600,root,INFO,| content-type=multipart/signed; protocol="application/pkcs7-signature"; micalg=sha-256; boundary="------------ms010908020707040304020406",description=None 2019-01-15 00:11:48,600,root,INFO,| content-type=text/plain; charset=utf-8; format=flowed,description=None 2019-01-15 00:11:48,600,root,INFO,| content-type=application/pkcs7-signature; name="smime.p7s",description=Firma criptográfica S/MIME 2019-01-15 00:11:48,600,root,INFO,| filename=smime.p7s,bytes=3998 2019-01-15 00:11:48,601,root,INFO,| Certificate: subject email_address=['bob.lumreeker@gmail.com'],not_valid_before=2018-10-03 00:00:00,not_valid_after=2019-10-03 23:59:59,hash_algorithm=sha256,key_size=2048 bytes, issuer={'countryName': 'GB', 'stateOrProvinceName': 'Greater Manchester', 'localityName': 'Salford', 'organizationName': 'COMODO CA Limited', 'commonName': 'COMODO RSA Client Authentication and Secure Email CA'} 2019-01-15 00:11:48,602,root,INFO,| Certificate: subject email_address=[],not_valid_before=2013-01-10 00:00:00,not_valid_after=2028-01-09 23:59:59,hash_algorithm=sha384,key_size=2048 bytes, issuer={'countryName': 'GB', 'stateOrProvinceName': 'Greater Manchester', 'localityName': 'Salford', 'organizationName': 'COMODO CA Limited', 'commonName': 'COMODO RSA Certification Authority'} 2019-01-15 00:11:48,616,root,INFO,| archivo escrito ./bob.lumreeker@gmail.com.crt,bytes=1870,ok=True

Para una verificación rápida, busca la última línea: si dice “archivo escrito”, entonces estás bien. El resto de esto muestra el proceso de verificación de DKIM y validación de certificados.

Empezaremos con esta parte, para que la tengamos completamente probada antes de dirigirnos a los webhooks de relé de entrada.

La aplicación web está incluida en el mismo proyecto de GitHub que las partes 1 – 3, así que si has seguido esas partes, ya la tienes. Aquí están las novedades:

  • Programa readSMIMEsig.py: lee un correo electrónico y extrae los certificados intermedios y de usuario.

  • Programa webapp.py: aplicación web compatible con Flask para usar con SparkPost Inbound Relay Webhooks.

  • webapp.ini: archivo de configuración para lo anterior. Un archivo de configuración permite que los mismos valores se pasen fácilmente tanto a las aplicaciones de línea de comandos como a las web.




Necesitas asegurarte de que tu host tenga el número de puerto TCP correcto abierto a solicitudes entrantes del exterior para que SparkPost pueda enviar mensajes a tu aplicación. Si estás alojado en AWS EC2, por ejemplo, necesitarás configurar el Security Group de tu instancia.

Las instrucciones para configurar y comenzar la aplicación web se dan aquí– es bastante fácil. Para comprobar que tu aplicación esté funcionando y sea accesible desde el exterior, puedes enviar solicitudes (en blanco) desde otro host utilizando curl, por ejemplo:

curl -X POST https://app.trymsys.net:8855/

Deberías ver una respuesta como:

{"message":"Content-Type desconocido en los encabezados de la petición"}

Esto es algo bueno: ¡tu aplicación está funcionando!

En webapp.log en tu host, verás una salida similar a esta:

2019-01-15 00:11:07,575,root,INFO,Request from 38.96.5.10,scheme=https,path=/ 2019-01-15 00:11:07,575,root,INFO,| len(headers)=3,len(body)=None 2019-01-15 00:11:07,575,root,INFO,| Content-Type desconocido: None

Para ayudarte a jugar con datos reales en tu aplicación rápidamente, puedes importar esta petición de Postman específica desde el repositorio del proyecto. Esto simula lo que hará tu cuenta de SparkPost, es decir, envía un POST https que contiene un correo electrónico con un certificado específico y válido (perteneciente a una cuenta de prueba mía) a tu aplicación.

Solo necesitas cambiar la dirección de destino en la petición (en el cuadro gris anterior) para que coincida con tu instalación. Si cambiaste el valor del token en webapp.ini, ajusta el valor del encabezado en Postman para que coincida.

Si tu aplicación está funcionando, verás una respuesta “200 OK” de regreso en Postman. El archivo webapp.log de tu host contendrá una salida como esta:

2019-01-15 00:11:48,554,root,INFO,Request from 38.96.5.10,scheme=https,path=/ 2019-01-15 00:11:48,554,root,INFO,| len(headers)=10,len(body)=14778 2019-01-15 00:11:48,555,root,INFO,| msg_from=bob.lumreeker@gmail.com,rcpt_to=secureme@inbound.thetucks.com,len(email_rfc822)=9223 2019-01-15 00:11:48,599,root,INFO,| from=bob.lumreeker@gmail.com,DKIM passed 2019-01-15 00:11:48,600,root,INFO,| content-type=multipart/signed; protocol="application/pkcs7-signature"; micalg=sha-256; boundary="------------ms010908020707040304020406",description=None 2019-01-15 00:11:48,600,root,INFO,| content-type=text/plain; charset=utf-8; format=flowed,description=None 2019-01-15 00:11:48,600,root,INFO,| content-type=application/pkcs7-signature; name="smime.p7s",description=Firma criptográfica S/MIME 2019-01-15 00:11:48,600,root,INFO,| filename=smime.p7s,bytes=3998 2019-01-15 00:11:48,601,root,INFO,| Certificate: subject email_address=['bob.lumreeker@gmail.com'],not_valid_before=2018-10-03 00:00:00,not_valid_after=2019-10-03 23:59:59,hash_algorithm=sha256,key_size=2048 bytes, issuer={'countryName': 'GB', 'stateOrProvinceName': 'Greater Manchester', 'localityName': 'Salford', 'organizationName': 'COMODO CA Limited', 'commonName': 'COMODO RSA Client Authentication and Secure Email CA'} 2019-01-15 00:11:48,602,root,INFO,| Certificate: subject email_address=[],not_valid_before=2013-01-10 00:00:00,not_valid_after=2028-01-09 23:59:59,hash_algorithm=sha384,key_size=2048 bytes, issuer={'countryName': 'GB', 'stateOrProvinceName': 'Greater Manchester', 'localityName': 'Salford', 'organizationName': 'COMODO CA Limited', 'commonName': 'COMODO RSA Certification Authority'} 2019-01-15 00:11:48,616,root,INFO,| archivo escrito ./bob.lumreeker@gmail.com.crt,bytes=1870,ok=True

Para una verificación rápida, busca la última línea: si dice “archivo escrito”, entonces estás bien. El resto de esto muestra el proceso de verificación de DKIM y validación de certificados.

3. Configuración de webhooks de SparkPost inbound relay

Primero, seleccionamos un dominio para usar como nuestra dirección de mensajes entrantes – aquí, será inbound.thetucks.com. Configure su dominio siguiendo esta guía. Aquí están los pasos que utilicé en detalle:




3.1 Añadir registros MX

Necesitarás acceso a tu cuenta específica de Proveedor de Servicios de Internet. Cuando termines, puedes verificarlos con dig – aquí está el comando para mi dominio.

dig +short MX inbound.thetucks.com

Deberías ver:

10 rx3.sparkpostmail.com. 10 rx1.sparkpostmail.com. 10 rx2.sparkpostmail.com.




3.2 Crear un Dominio Entrante

Usa la colección de API de Postman de SparkPost, seleccionando la llamada Inbound Domains / Create .. El cuerpo de la solicitud POST contiene tu dominio, por ejemplo:

{    "domain": "inbound.thetucks.com" }




3.3 Crear un Webhook de Retransmisión

Crea un webhook de retransmisión entrante usando la llamada relevante de Postman. El cuerpo del mensaje en mi caso contiene:

{ "name": "Certificate Collection Webhook", "target": "https://app.trymsys.net:8855/", "auth_token": "t0p s3cr3t t0k3n", "match": { "protocol": "SMTP", "domain": "inbound.thetucks.com" } }

Como mencioné antes, recomiendo establecer un auth_token a tu propio valor secreto, como se establece en el archivo webapp.ini en tu host.

Tu valor "target" necesita coincidir con la dirección de tu host y el puerto TCP donde estarás alojando la aplicación web.

Tu valor "domain" necesita coincidir con tus registros MX configurados en el paso 1.







¡Eso es todo! La instalación está completa. Deberías poder enviar certificados a tu dirección de entrada, serán procesados y aparecerán en el host de tu aplicación web – en este caso, un archivo llamado bob.lumreeker@gmail.com.crt.

Ahora puedes enviar emails cifrados a Bob, usando las herramientas descritas en las partes 2 y 3 de esta serie.

Puedes examinar el contenido de un certificado usando:

openssl x509 -inform PEM -in bob.lumreeker\@gmail.com.crt -text -noout

4. Internals: DKIM checking, validación de certificados

La aplicación verifica que los correos electrónicos recibidos tengan DKIM válidos y verifica que los propios certificados sean válidos, como se describe aquí. También hay notas de implementación allí, e ideas para trabajo futuro.

Resumiendo…

Hemos visto cómo se pueden recopilar fácilmente las claves públicas de los destinatarios usando un correo electrónico a una dirección de webhook de retransmisión entrante. Una vez hecho, esos destinatarios pueden recibir sus mensajes en forma cifrada S/MIME.

¡Eso es todo por ahora! Felices envíos.

Únete a nuestro Newsletter.

Mantente al día con Bird a través de actualizaciones semanales en tu buzón.

Al enviar, aceptas que Bird pueda contactarte sobre nuestros productos y servicios.

Puedes darte de baja en cualquier momento. Consulta el Aviso de Privacidad de Bird para obtener detalles sobre el procesamiento de datos.

Únete a nuestro Newsletter.

Mantente al día con Bird a través de actualizaciones semanales en tu buzón.

Al enviar, aceptas que Bird pueda contactarte sobre nuestros productos y servicios.

Puedes darte de baja en cualquier momento. Consulta el Aviso de Privacidad de Bird para obtener detalles sobre el procesamiento de datos.

Únete a nuestro Newsletter.

Mantente al día con Bird a través de actualizaciones semanales en tu buzón.

Al enviar, aceptas que Bird pueda contactarte sobre nuestros productos y servicios.

Puedes darte de baja en cualquier momento. Consulta el Aviso de Privacidad de Bird para obtener detalles sobre el procesamiento de datos.

Pinterest logo
Uber logo
Square logo
Logo de Adobe
Meta logo
PayPal logo

Company

Configuración de privacidad

Newsletter

Mantente al día con Bird a través de actualizaciones semanales en tu buzón.

Al enviar, aceptas que Bird pueda contactarte sobre nuestros productos y servicios.

Puedes darte de baja en cualquier momento. Consulta el Aviso de Privacidad de Bird para obtener detalles sobre el procesamiento de datos.

Uber logo
Square logo
Logo de Adobe
Meta logo

Company

Configuración de privacidad

Newsletter

Mantente al día con Bird a través de actualizaciones semanales en tu buzón.

Al enviar, aceptas que Bird pueda contactarte sobre nuestros productos y servicios.

Puedes darte de baja en cualquier momento. Consulta el Aviso de Privacidad de Bird para obtener detalles sobre el procesamiento de datos.

Uber logo
Logo de Adobe
Meta logo

Reach

Grow

Manage

Automate

Recursos

Company

Newsletter

Mantente al día con Bird a través de actualizaciones semanales en tu buzón.

Al enviar, aceptas que Bird pueda contactarte sobre nuestros productos y servicios.

Puedes darte de baja en cualquier momento. Consulta el Aviso de Privacidad de Bird para obtener detalles sobre el procesamiento de datos.