Cómo firmar correos electrónicos con GPG y JavaMail

Publicado por pico.dev el .
blog-stack java planeta-codigo planeta-linux programacion seguridad
Comentarios

El correo electrónico es un medio muy utilizado para realizar ataques de phising, algunos son muy burdos pero seguramente algunos usuarios sin muchos conocimientos caen víctimas de ellos y aún los usuarios con conocimientos también pueden serlo si están bien realizados y muestran un correo electrónico exactamente igual que el que intentan suplantar. Los usuarios son las víctimas pero si los sitios web que envían los correos electrónicos legítimos los firmasen digitalmente sería una garantía más para proteger a sus usuarios, pudiendo detectar de otra forma el spam y phising. En este artículo muestro a modo de ejemplo como firmar un correo electrónico con GPG y JavaMail e igualmente podría utilizarse para cifrarlo, aunque usar DKIM sería lo más apropiado.

Java
GnuPG

Los sitios de comercio electrónico y muchas páginas web utilizan el protocolo seguro HTTPS para cifrar los datos intercambiados entre cliente y servidor impidiendo a una tercera persona conocer qué información se está transmitiendo, además impide que puedan ser alterados sin su conocimiento. Es habitual usar HTTPS y certificados en las páginas de compra en las que hay que introducir datos personales junto con la tarjeta de crédito también en las cuentas de usuario como forma de proporcionar seguridad y proteger la información personal. Generando y usando certificados TLS/SSL en el servidor el sitio y el usuario evitan caer en un ataque de phising en la que una tercera persona con intenciones maliciosas intenta suplantar la identidad del sitio web.

Pero los ataques de phising también son realizados a través del correo electrónico, mensajes en los que se incluyen enlaces hacia páginas que suplantan a un sitio. Algunos usuarios quizá no se den cuenta de la suplantación al hacer clic en los enlaces maliciosos. Los motores de búsqueda mantendrán a los usuarios a salvo de enlaces maliciosos en las páginas de resultados que les lleven a páginas de phising, pero no del correo electrónico que si no es detectado como spam llegará a la bandeja de entrada de los usuarios. El correo electrónico es una vía para llevar a los usuarios hacia esas páginas de phising. Para evitar este posible peligro no todos los sitios web y de comercio electrónico son los que firman sus mensajes como forma de verificar la autenticidad de los mismos así como evitar que pueda ser modificados sin conocimiento.

Con GPG y JavaMail podemos firmar los mensajes electrónicos que enviemos desde una aplicación Java. La firma de un correo electrónico consiste baśicamente en firmar el contenido del mensaje y adjuntar la firma como un documento adjunto con un mimetype de application/pgp-signature. Lo primero que deberemos hacer es generar un par de claves de cifrado asimétrico usando GPG. Si los mensajes los vamos a enviar usando un cuenta de gmail y tenemos activada la verificación en dos pasos debemos genera una contraseña de aplicación desde Mi cuenta de Google.

Además de cómo firmar un correo electrónico el siguiente ejemplo muestra cómo ejecutar un proceso del sistema en Java que nos proporciona acceso a todas las utilidades GNU, scripts de Python u otros comandos que tenga instalados, también muestra cómo enviar un correo electrónico en un programa Java que ya comenté pero ahora con un ejemplo ejecutable y enviando un archivo adjunto.

En este ejemplo solo se firma el contenido del mensaje quedando fuera de la firma el asunto, fecha, otros adjuntos y destinatarios del mensaje pero podría utilizarse lo mismo para firmar estos otros datos. Enviado el correo electrónico podemos verificar la firma con el siguiente comando de GPG.

Verificación de la firma GPG del correo electrónico

En el anillo de claves de GPG la clave que usemos para firmar no ha de tener passphrase de lo contrario cuando se ejecute el comando GPG la solicitará en una ventana emergente. Aunque con las opciones –passphrase y –batch no debería solicitarla no he conseguido evitarlo.

El código fuente completo del ejemplo puedes descargarlo del repositorio de ejemplos de Blog Bitix alojado en GitHub y probarlo en tu equipo ejecutando el comando ./gradlew --daemon run -Pargs="[contraseña de aplicación de cuenta gmail]".

Las suplantaciones mediante correo electrónico son y seguirán siendo habituales si no son detectadas como spam. Después de escribir este artículo usar DKIM parece ser la forma adecuada de firmar y cifrar los correos electrónicos y viendo el mensaje original de los que envían Google y Amazon es lo que utilizan ellos que algo sabrán de esto. Usar DKIM en los correos electrónicos será tema para otro posible artículo, la nube de Amazon ofrece soporte para DKIM.

Yo apoyo al software libre