Sé que el correo electrónico es intrínsecamente inseguro de todos modos, pero teniendo en cuenta que prácticamente todos los destinatarios del correo electrónico están usando un proveedor de nube grande y de cierta confianza (sugerencia, comienza con G). Supongo que la mayoría de mi correo electrónico es enviados a través de MTA relativamente seguros que requieren o prefieren usar TLS.
A partir de ese supuesto, llegaría a la conclusión de que si quisiera alojar mi propio servidor de correo electrónico y si me importara la seguridad, DEBE ser compatible con TLS y tener un certificado firmado por una autoridad confiable.
Ok, está bien, puedo configurarlo yo mismo. Pero, ¿y si quiero auto-alojar este servidor? Sé que puedo pagarle fácilmente a un proveedor de la nube para que me la aloje, pero tengo un deseo irracional de escapar de la nube por completo y construir mi propia infraestructura.
Sin embargo, eso abre un host (sin juego de palabras) de otros problemas. La entrega de correo electrónico desde direcciones IP residenciales es irregular en el mejor de los casos. El acceso a Internet y la electricidad no tienen un tiempo de actividad del 100% en las áreas residenciales. Tal vez estropee mi servidor y tenga que volver a implementarlo. O tal vez tengo que bajarlo para actualizarlo.
Entonces, tal vez quiera alquilar una máquina virtual de un proveedor de la nube y ejecutar un servidor SMTP, pero al mismo tiempo no quiero que mi clave privada salga de mi propia máquina.
Soy un programador muy capaz, por lo que estoy considerando realmente intentar esto. Simplemente no estoy seguro de si es físicamente posible dado el protocolo TLS.
Estaba estudiando detenidamente este archivo, enlace , una implementación javascript de TLS, tratando de averiguar cómo se podría hacer. Encontré este diagrama de estado de red:
* =======================FULL HANDSHAKE======================
* Client Server
*
* ClientHello -------->
* ServerHello
* Certificate*
* ServerKeyExchange*
* CertificateRequest*
* <-------- ServerHelloDone
* Certificate*
* ClientKeyExchange
* CertificateVerify*
* [ChangeCipherSpec]
* Finished -------->
* [ChangeCipherSpec]
* <-------- Finished
* Application Data <-------> Application Data
También estaba hojeando este artículo: enlace
Parece que los pasos marcados con un asterisco son opcionales de acuerdo con el protocolo. En general, como lo entiendo, se supone que el cliente y el servidor comparten claves públicas, computan individualmente y por separado un secreto compartido, negocian un cifrado y luego comienzan la comunicación a través de ese cifrado de mutuo acuerdo utilizando el secreto compartido como una semilla en ambos lados.
Si fuera a hacer esto, supongo que tendría que crear una implementación de TLS ligeramente aumentada, llamémosla "YesTLS".
YesTLS es estúpido, pero muy extrovertido. Intentará complacer a todos los que le hablan, aunque no tenga idea de lo que están diciendo. Lo configuraría con mis claves públicas y cualquier otro dato requerido, y luego respondería a las conexiones TCP en ciertos puertos que escucho en mi aplicación. La idea es que si el cliente remoto no solicita una firma digital única para verificar que está hablando con el "propietario de la clave" y cree que sí lo está, entonces mi servidor no necesita tener la clave. Simplemente puede almacenar los paquetes cifrados a medida que los recibe. Luego, mi servidor, que en realidad tiene sus claves, puede solicitar esas conexiones grabadas una por una cuando esté listo, y volver a aplicarlas utilizando las claves privadas reales, para recibir los mensajes cifrados.
De esta manera puedo limitar el almacenamiento de correos electrónicos de texto sin formato.
¿Sería esto realmente posible con TLS? Quiero hacer una revisión rápida de la cordura antes de comenzar a intentar que suceda.
mail.google.com yes-TLS-smtp-server trusted-smtp-server
X <--- config with pubkey <---
~
---> request TLS connection ---> X
X <--- send public key <-----
---> send public key ---> X
X <--- ok, i'm ready <---
---> encrypted stream ---> X
~
X <--- get new emails <---
---> send google public key --> X
---> and other session info --> X
X <--- ok, i'm ready <---
---> encrypted stream ---> X
should be decryptable?