Cifrar con gpg

17 de diciembre 2018ComentarioslinuxDavid Poza SuárezComentarios

Hoy vamos a conocer un sistema libre para cifrar nuestros archivos basado en criptografía asimétrica, llamado GnuPG o gpg. Un método muy seguro, rápido y gratuito para cifrar datos y así poder enviar información sensible por correo electrónico o cualquier otro medio.

¿Qué es la criptografía asimétrica?

Es un método para cifrar datos en el que existe un par de claves asociadas entre sí: La clave pública y la clave privada. Es necesario un par de claves por cada usuario para lograr una comunicación en los dos sentidos.

La pública se puede compartir con tantas personas como deseemos, y sirve para cifrar los mensajes.

La privada es aquella a la que sólo el propietario de los datos cifrados puede tener acceso, por tanto no podemos compartirla con nadie. Esta clave únicamente puede descifrar aquellos datos que fueron cifrados con su clave pública asociada. Es además un clave única, el algoritmo para generarla garantiza que no puede generarse otra igual.

Un ejemplo de uso sería el siguiente: Alguien desea enviarnos información de acceso a un servicio web, por lo tanto información muy sensible, y para ello cifra un archivo de texto con dicha información usando nuestra clave pública (que previamente hemos compartido con él).

De este modo, cuando nos mande el fichero por correo electrónico solo nosotros podremos descifrar su contenido gracias a que sólo nosotros poseemos la clave privada asociada a la pública con que fue cifrado. No importaría si el correo es interceptado porque no tendrían la clave privada.

Por lo tanto la principal ventaja de la criptografía asimétrica frente a la clásica criptografía simétrica (la misma clave se usa la cifrar y también para descifrar), es que nunca compartimos la clave que descifra el mensaje.

¿Qué es GnuPg?

Gpg es el acrónimo de GNU Privacy Guard, y es un sustituto del PGP (Pretty Good Privacy) creado por Werner Koch como software libre multiplataforma para el cifrado simétrico y asimétrico (el que nos interesa). Viene incorporado en la mayoría de distribuciones Linux y puede también usarse en MacOS o Windows. En este último existe GPG4Win pero también podemos usarlo con la integración de Bash en Windows 10.

Generar claves pública y privada

gpg --gen-key

Nos preguntará qué algoritmo usar, nos da a elegir entre RSA o DSA, elegiremos la opción RSA y 4096 bits (el tamaño máximo permitido) porque actualmente se prefiere a DSA, por ejemplo openssh 7.0 y superiores han deshabilitado DSA por defecto.

Después nos preguntará si deseamos poner una fecha de caducidad a las claves, pero esto no es importante ya que no aporta más seguridad que crear un certificado de revocación, que veremos a continuación. Lo dejamos en un valor 0: sin fecha de expiración.

El siguiente paso es rellenar información personal para identificar la clave: Nombre, email y un comentario opcional.

Y para terminar debemos poner una clave(passphrase) para proteger la clave privada.

Crear certificado de revocación

Es un fichero que generamos como medida de seguridad para que ante la situación de haber olvidado la passphrase de nuestra clave privada o si ha sido comprometida, podamos bloquear el uso de la clave pública asociada. Por ello recomiendo generar uno justo después de haber creado nuestro par de claves, aunque podríamos hacerlo en cualquier momento si tenemos acceso a la clave privada y su passphrase.

Al igual que la clave privada hay que mantenerlo en un lugar seguro, pues quién lo posea tiene el poder de cancelar tus claves. No obstante no sirve para cifrar ni descifrar mensajes.

Lo generamos así:

gpg -a --output cert-revocacion.txt --gen-revoke XXXXXXXX

// la opción -a es opcional, para generar el certificado en ascii, para poder guardarlo en un gestor de contraseñas, por ejemplo

//XXXXXXXX puede ser el identificador de clave pública o el de la clave privada, ambos identifican el par de claves que se revocaría el certificado.

Revocar el par de claves

Para revocar efectivamente un par de claves, simplemente tenemos que importar a nuestro llavero el certificado de revocación y después subir la clave pública al servidor de claves.

gpg --import cert-revocacion.txt gpg --send-keys --keyserver urlservidor XXXXXXXX

Una vez hemos revocado una clave, si hacemos un listado veremos que sale indicado del siguiente modo:

pub   2048R/XXXXXXXX 2018-12-16 \[revoked: 2018-12-17\]
uid                  prueba2 (dd) <prueba2@gmail.com>

Evidentemente de nada sirve revocar la clave pública en el servidor de claves si luego los usuarios no actualizan sus llaveros (Ver Actualizar llaves).

Listar las claves

Para ver un listado de claves instaladas en nuestro llavero(keyring) junto a su identificador hash, el nombre del propietario y la fecha de creación:

gpg --list-keys [filtro]

Habitualmente vamos a ejecutar este comando para ver el identificador alfanumérico de la clave pública, que viene indicado justo después de la palabra pub, un carácter y el número de bits que posee. También podemos ver el hash de la clave privada después de la palabra sub. Sub, en realidad hace referencia a subclave privada, Ver apartado Subclaves.

El carácter nos indica el tipo de clave:

  • R: RSA
  • D: DSA
  • g: ElGamal
pub      4096R/XXXXXXXX 2018-10-02
uid                     David Poza Suárez <correo@gmail.com>
sub      4096R/YYYYYYYY 2018-10-02

Importar una clave pública

Cuando queramos enviar un mensaje cifrado a alguien, lo primero que tendremos que hacer es pedirle su clave pública para cifrar con ella y de este modo sólo él pueda leer su contenido.

gpg --import manuel.gpg

Después de importar la clave la podremos ver en nuestro fichero llavero si usamos el comando del punto anterior.

Cifrar un archivo con la clave pública

Una vez tenemos importada la clave pública de un destinatario y hemos localizado su identificador hash dentro del listado de llaves, solo queda teclear el siguiente comando:

gpg --encrypt --recipient XXXXXXXX fichero

Esto nos genera el fichero cifrado que tendrá la extensión .gpg.

Descifrar un archivo con la clave privada

Si nos ponemos en el caso de recibir un mensaje cifrado usando nuestra clave privada, podremos descifrarlo mediante nuestra clave privada usando el siguiente comando:

gpg [--output fichero_descifrado] --decrypt fichero_cifrado.gpg

Se nos muestra la información asociada a la clave pública usada para cifrar el fichero, es decir, el destinatario y además en nuestro caso se nos pedirá introducir la passphrase que pusimos a la clave privada en el momento de generarla.

Compartir nuestra clave pública

Cuando queramos que alguien sea capaz de enviarnos información cifrada, lo primero es compartir con él nuestra clave pública, para lo que tenemos dos opciones.

Exportar clave pública

Podemos exportar una clave pública, solo tendremos que indicar el identificador hash pub de nuestra clave, que encontraremos si hacemos un listado del llavero. Una vez tengamos el fichero de salida simplemente lo compartimos usando nuestro medio preferido.

gpg --output clave-publica.gpg --export XXXXXXXX

Usar un servidor de llaves público

Otra opción es usar servidores gratuitos de claves gpg, donde podemos subir nuestra clave pública. Algunos ejemplos son:

Podemos subir la clave desde un navegador usando una interfaz web o bien directamente desde la terminal indicando el identificador de la clave que deseamos subir en el siguiente comando gpg:

gpg --send-keys --keyserver pgp.rediris.es XXXXXXXX

Una vez hemos subido nuestra clave pública a un servidor, cualquiera de nuestros contactos puede descargarla simplemente conociendo el hash.

gpg --keyserver pgp.rediris.es --recv XXXXXXXX

Firmar ficheros

Firmar un fichero sirve por ejemplo para que cuando alguien me envía un fichero cifrado con mi clave pública, además yo pueda saber de quién se trata. En este caso el que envía el mensaje debe de firmar el fichero con su clave privada antes de encriptarlo.

//aqui se usa la clave privada
// podemos firmar con --sign si queremos firmar en binario y comprimir el fichero
// o podemos firmar con --clearsign para firmar en texto plano si queremos que siga siendo legible.

gpg -u XXXXXXXX --output documento-firmado.sig --clearsign documento-sin-firmar

Ver firma de un fichero

Podemos ver quién ha firmado un fichero cuando lo desencriptamos usando --decrypt, el comando nos avisa con un mensaje del tipo:

gpg: Signature made Mon 17 Dec 2018 09:14:59 AM STD using RSA key ID XXXXXXXX gpg: Good signature from "David Poza Suárez correo@gmail.com"

También podríamos comprobar la firma exclusivamente en caso de tener un fichero no cifrado:

gpg --verify documento-firmado.sig

Subclaves

Ya que nuestro par de claves nos representa en internet, lo ideal es que nuestra clave privada nos dure para siempre, para lo cual hay que mantenerla protegida todo lo posible, por lo que lo mejor es tenerla en un lugar totalmente inaccesible. Por desgracia esto no es práctico.

Aquí es donde aparecen las subclaves. Una subclave es una clave que depende de una clave maestra y se usa en lugar de ésta. Pueden anularse y crearse tantas como queramos si por ejemplo son comprometidas, pero siempre mantendremos la clave maestra segura para poder generar nuevas subclaves.

Para crear una subclave debemos entrar en el modo interactivo de gpg:

gpg --edit-key XXXXXXXX
addkey //seguimos indicaciones del asistente
save // salvamos los cambios antes de salir del modo interactivo

Ahora si listamos las claves del llavero podremos ver que tenemos dos subclaves privadas después de la palabra sub (subclave).

pub   2048R/XXXXXXXX 2018-10-02
uid                  David Poza Suárez <prueba@gmail.com>
sub   2048R/YYYYYYYY 2018-10-02
sub   2048R/ZZZZZZZZ 2018-12-17

Backup de nuestra claves

Nuestras claves públicas y privadas se almacenan por defecto en dos llaveros: ~/.gnupg/pubring.gpg y ~/.gnupg/secring.gpg respectivamente. Por lo tanto lo más sencillo es hacer backup de la carpeta  ~/.gnupg al completo.

Otra opción es exportar la clave privada concreta que queremos salvar.

gpg -u XXXXXXXX --output claveprivada.gpg --export-secret-keys

Otras operaciones

Borrar clave privada

gpg --delete-secret-keys XXXXXXXX

Borrar clave pública

gpg --delete-key XXXXXXXX

Desacoplar la firma de un fichero firmado

Cuando firmamos un fichero con --sign el fichero deja de ser legible así que debemos quitar la firma para que volvamos a tener el fichero original.

gpg --output documento-firmado.sig --detach-sig documento-original

Actualizar llaves

Es importante realizar una actualización de nuestro llavero de claves con cierta frecuencia, ya que los identificadores de usuario o estado de revocación pueden haber cambiado con el tiempo. Para ello:

gpg --refresh-keys

Más información

Dado que gpg es bastante complejo y existen muchas opciones, si tenemos cualquier duda, lo mejor es acudir a su documentación oficial.