Cifrado asimétrico con GPG y OpenSSL

Índice

Generación de claves

Creación de claves con GPG

Para generar un par de claves se usa el comando gpg --gen-key:

❯ gpg --gen-key
gpg (GnuPG) 2.2.27; Copyright (C) 2021 Free Software Foundation, Inc.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

Nota: Usa "gpg --full-generate-key" para el diálogo completo de generación de clave.

GnuPG debe construir un ID de usuario para identificar su clave.

Nombre y apellidos: Javi Huete 
Dirección de correo electrónico: correo@correo.org
Está usando el juego de caracteres 'utf-8'.
Ha seleccionado este ID de usuario:
    "Javi Huete  <correo@correo.org>"

¿Cambia (N)ombre, (D)irección o (V)ale/(S)alir? v
Es necesario generar muchos bytes aleatorios. Es una buena idea realizar
alguna otra tarea (trabajar en otra ventana/consola, mover el ratón, usar
la red y los discos) durante la generación de números primos. Esto da al
generador de números aleatorios mayor oportunidad de recoger suficiente
entropía.
Es necesario generar muchos bytes aleatorios. Es una buena idea realizar
alguna otra tarea (trabajar en otra ventana/consola, mover el ratón, usar
la red y los discos) durante la generación de números primos. Esto da al
generador de números aleatorios mayor oportunidad de recoger suficiente
entropía.
gpg: clave 6E42360E895488ED marcada como de confianza absoluta
gpg: creado el directorio '/home/javi/.gnupg/openpgp-revocs.d'
gpg: certificado de revocación guardado como '/home/javi/.gnupg/openpgp-revocs.d/4A914508FF0E1A5087F727166E42360E895488ED.rev'
claves pública y secreta creadas y firmadas.

pub   rsa3072 2024-12-12 [SC] [caduca: 2026-12-12]
      4A914508FF0E1A5087F727166E42360E895488ED
uid                      Javi Huete  <correo@correo.org>
sub   rsa3072 2024-12-12 [E] [caduca: 2026-12-12]

Las claves se guardan en el fichero pubring.kbx dentro del directorio oculto .gnupg en el home del usuario.

Listar las claves públicas

Para listar las claves públicas se usa el comando gpg --list-keys:

❯ gpg --list-keys
/home/javi/.gnupg/pubring.kbx
---------------------------------
pub   rsa3072 2024-12-12 [SC] [caduca: 2026-12-12]
      4A914508FF0E1A5087F727166E42360E895488ED
uid        [  absoluta ] Javi Huete  <correo@correo.org>
sub   rsa3072 2024-12-12 [E] [caduca: 2026-12-12]

La salida de este comando aporta información relevante sobre la clave almacenada. En primer lugar, se muestra el fichero en el que se almacenan las claves.

/home/javi/.gnupg/pubring.kbx

A continuación se recogen los detalles de las claves públicas del usuario. La primera parte de la información hace referencia a la clave pública: pub.

Se muestra el algoritmo de encriptación y el tamaño de la clave: rsa3072, es decir, una clave que usa el algoritmo de encriptación RSA y que tiene un tamaño de 3072 bits.

Después aparece la fecha de creación: 2024-12-12.

El siguiente campo indica el uso de la clave: [SC], en este caso se puede usar para firmar (Sign) y certificar (key Certification).

Después, se muestra la fecha de caducidad de la clave: [caduca: 2026-12-12].

Y el último campo de esta primera fila es la huella o fingerprint: 4A914508FF0E1A5087F727166E42360E895488ED. Esta huella se puede usar para referirse de forma más corta a la clave que si se muestra completa en formato ASCII contiene cientos de caracteres.

En la segunda fila se muestra la información sobre la identificación del usuario asociada a la clave pública: uid.

Después se indica el nivel de confianza en la clave: [ absoluta ].

Y también el nombre y correo electrónico del usuario que se han indicado durante la creación de la clave: Javi Huete <correo@correo.org>

La tercera parte de la firma recoge la información sobre la subclave de encriptación relacionada con la clave pública: sub.

En esta línea se muestra el algoritmo y tamaño de la clave: rsa3072.

El uso de la clave: [E], en este caso se puede usar para encriptar comunicaciones y ficheros almacenados.

Y, por último, se indica también la fecha de caducidad: [caduca: 2026-12-12].

Para establecer un periodo de validez durante la creación de un par de claves se usa el argumento expire del comando gpg --key-gen. Este argumento soporta varios formatos como por ejemplo el formato ISO (YYYY-MM-DD). Así, para hacer que el par de claves caduque en un mes se debería usar el argumento months=1 al ejecutar el comando gpg --key-gen para generar el par de claves.

Listar las claves privadas

Para listar las claves privadas se usa el comando gpg --list-secret-keys.

❯ gpg --list-secret-keys
/home/javi/.gnupg/pubring.kbx
---------------------------------
sec   rsa3072 2024-12-12 [SC] [caduca: 2026-12-12]
uid        [  absoluta ] Javi Huete  <correo@correo.org>
ssb   rsa3072 2024-12-12 [E] [caduca: 2026-12-12]

Importar y exportar claves con GPG

Para exportar la clave pública se usa el comando gpg --export.

gpg --export > javi_huete.asc

De la misma forma, para importar una clave pública se usa el comando gpg --import.

❯ gpg --import juan_pineda.asc 
gpg: clave 35045657E85B4EAA: clave pública "Juan Pineda" <a@a.com>" importada
gpg: Cantidad total procesada: 1
gpg:               importadas: 1

Con el comando gpg --list-key se comprueba que la clave pública se ha importado correctamente.

❯ gpg --list-key
/home/javi/.gnupg/pubring.kbx
---------------------------------
pub   rsa3072 2024-12-12 [SC] [caduca: 2026-12-12]
      4A914508FF0E1A5087F727166E42360E895488ED
uid        [  absoluta ] Javi Huete  <correo@correo.org>
sub   rsa3072 2024-12-12 [E] [caduca: 2026-12-12]

pub   rsa3072 2024-12-12 [SC] [caduca: 2026-12-12]
      1B0B8EA692D1C32493D20E5535045657E85B4EAA
uid        [desconocida] Juan Pineda <a@a.com>
sub   rsa3072 2024-12-12 [E] [caduca: 2026-12-12]

Cifrado asimétrico con claves públicas

Para cifrar un fichero usando la clave pública del destinatario se puede usar el siguiente comando:

❯ gpg -se -r raulhr fichero.txt 
gpg: 33DC17FB92D2D65A: No hay seguridad de que esta clave pertenezca realmente
al usuario que se nombra

sub  rsa3072/33DC17FB92D2D65A 2024-12-13 raulhr <raulhr@correo.org>
 Huella clave primaria: D2B4 66A2 EA5E AFA3 D01E  D7C5 F9E5 1736 F896 495A
      Huella de subclave: F6CD 0599 A6EE C8A1 B6AA  D9AF 33DC 17FB 92D2 D65A

No es seguro que la clave pertenezca a la persona que se nombra en el
identificador de usuario. Si *realmente* sabe lo que está haciendo,
puede contestar sí a la siguiente pregunta.

¿Usar esta clave de todas formas? (s/N) s

Para descifrar un mensaje recibido que ha sido cifrado usando nuestra clave pública, se usa la opción -d del comando gpg. Para que el contenido del fichero se almacene en un fichero y no sólo se muestre por pantalla es necesario usar también la opción -o.

❯ gpg -o pokemon.txt -d pokemon.txt.gpg
gpg: cifrado con clave de 3072 bits RSA, ID 1129E3EA155B0A3B, creada el 2024-12-13
      "Javi Huete  <correo@correo.org>"
gpg: Firmado el vie 13 dic 2024 13:36:20 CET
gpg:                usando RSA clave XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
gpg:                emisor "raulhr@correo.org"
gpg: Firma correcta de "raulhr <raulhr@correo.org>" [desconocido]
gpg: ATENCIÓN: ¡Esta clave no está certificada por una firma de confianza!
gpg:          No hay indicios de que la firma pertenezca al propietario.
Huellas dactilares de la clave primaria: XXXX XXXX XXXX XXXX XXXX XXXX

Si otra persona recibe el mensaje no lo puede descifrar

⟩ gpg --decrypt fichero.txt.gpg
gpg: cifrado con clave RSA, ID 33DC17FB92D2D65A
gpg: descifrado fallido: No secret key

Tanto las claves públicas como privadas almacenadas en el keyring se pueden borrar usando el comando gpg. Este comando cuenta con una opción para el borrado de todas las claves públicas y otra para el borrado de todas las claves privadas.

--delete-keys           elimina claves del almacén público
--delete-secret-keys    elimina claves del almacén privado

Exportar clave a un servidor público de claves PGP

Para generar una clave de revocación de la clave pública se usa la opción --gen-revoke del comando gpg. Este comando es interactivo y permite añadir al certificado de revocación de la clave pública una razón para la revocación entre una lista y, además, permite añadir también un comentario.

❯ gpg --gen-revoke "Javi Huete "

sec  rsa3072/6E42360E895488ED 2024-12-12 Javi Huete  <correo@correo.org>

¿Crear un certificado de revocación para esta clave? (s/N) s
Por favor elija una razón para la revocación:
  0 = No se dio ninguna razón
  1 = La clave ha sido comprometida
  2 = La clave ha sido reemplazada
  3 = La clave ya no está en uso
  Q = Cancelar
(Probablemente quería seleccionar 1 aquí)
¿Su decisión? 0
Introduzca una descripción opcional; acábela con una línea vacía:
> Certificado de revocación generado por si aparece algún problema al compartir la clave pública en un servidor de claves
> 
Razón para la revocación: No se dio ninguna razón
Certificado de revocación generado por si aparece algún problema al compartir la clave pública en un servidor de claves
¿Es correcto? (s/N) s
se fuerza salida con armadura ASCII.
-----BEGIN PGP PUBLIC KEY BLOCK-----
Comment: This is a revocation certificate

iQIwBCABCgCaFiEESpFFCP8OGlCH9ycWbkI2DolUiO0FAmdcEpV8HQBDZXJ0aWZp
Y2FkbyBkZSByZXZvY2FjacOzbiBnZW5lcmFkbyBwb3Igc2kgYXBhcmVjZSBhbGfD
um4gcHJvYmxlbWEgYWwgY29tcGFydGlyIGxhIGNsYXZlIHDDumJsaWNhIGVuIHVu
IHNlcnZpZG9yIGRlIGNsYXZlcwAKCRBuQjYOiVSI7dIOC/9C1hOkkUxkrJN92fUL
6BrqctyIUkkoWeMM9Kx6ihpsFmAYRkBTzHFZ4xZuVGtR5VrzIhQ+amPvZElLnlAO
6TibJ3w/ndrBBR391z0KCSzf0mhGBIo8RdJ/R3i3SScYHCDusRERRcqi5UGIdnp6
QG6lt4Zy0x/9hux/gBhN9t6Rx8J/orW4AQXUwWaA9rvlp5hw+5nqHk62BlTcl3G7
9CWQSPz0wcrNJ/hnNiMNa0XBMh9MI0mKbNT+BTM62l7UITC0C208fIzCULJgUzvw
j+GQ594RTCBCV2xrR5vJHAbvHjrIpn7KlLko/z8vwXFBzVuklbKibmwRivfmTOy8
aCdEceyBeryJ/cwaCUshr7OBEDP8MBASBNmrSoW5DT+cTOSqgWF5ZsrG6zA+KmKz
9EG2o2RKjlKOB1WLtfddZcUDH+m2ozBdT9kiemtj1VecSf8bSQe9zSCNtKpndlin
3bzJEHl+ACDyomvFhfr6y6yCkqiTIzIeDT3FQ7z5oggdGQY=
=cY5D
-----END PGP PUBLIC KEY BLOCK-----
Certificado de revocación creado.

Por favor consérvelo en un medio que pueda esconder; si alguien consigue
acceso a este certificado puede usarlo para inutilizar su clave.
Es inteligente imprimir este certificado y guardarlo en otro lugar, por
si acaso su medio resulta imposible de leer. Pero precaución: ¡el sistema
de impresión de su máquina podría almacenar los datos y hacerlos accesibles
a otras personas!

Para exportar una clave pública al servidor de claves por defecto de openpgp (hkps://keys.openpgp.org) se usa la opción --send-keys del comando gpg. Con la opción --keyserver se puede especificar también el servidor al que se envía la clave.

❯ gpg --keyserver pgp.rediris.es --send-keys 4A914508FF0E1A5087F727166E42360E895488ED
gpg: enviando clave 6E42360E895488ED a hkp://pgp.rediris.es

Para importar una clave pública desde un servidor primero hay que buscar el identificador de la clave con la opción --search-keys del comando gpg.

❯ gpg --keyserver pgp.rediris.es --search-keys "nombre"
gpg: data source: http://130.206.1.8:11371
(1)	Nombre <correo@correo.org>
	  3072 bit RSA key E68CA61054C58A9E, creado: 2024-12-13, caduca: 2026-12-13
(2)	Pedro (Contraseña CriptoAsimetrica) <nombre@gmail.c
	  3072 bit RSA key 5252337E783EC15B, creado: 2023-10-17
(3)	Angelika <nombre@gmail.com>
	  4096 bit RSA key 2FC32C6A3FE01D57, creado: 2017-04-01, caduca: 2021-04-01 (caducada)
(4)	Marc <marc@gmail.com>
	  3072 bit RSA key 428D682E205EF071, creado: 2016-07-26
...
(20)	GINES SANS <GIALBA@santandersupernet.com>
	  1024 bit DSA key 6E94CCF6237D0F00, creado: 1998-06-28
Keys 12-20 of 20 for "nombre".  Introduzca número(s), O)tro, o F)in > q

Con el identificador de la clave se puede importar desde el servidor usando la opción --receive-keys

❯ gpg --keyserver pgp.rediris.es --receive-keys E68CA61054C58A9E
gpg: clave E68CA61054C58A9E: clave pública "Alejandro <alejandro@correo.org>" importada
gpg: Cantidad total procesada: 1
gpg:               importadas: 1

Cifrado asimétrico con OpenSSL

Para generar un par de claves con openssl se usa el comando openssl genrsa.

Primero se genera la clave privada.

❯ openssl genrsa -out javi_huete.pem 2048

Y, a partir de ella, se genera la pública.

❯ openssl rsa -in javi_huete.pem -pubout -out javi_huete.pub
writing RSA key

Para cifrar un fichero de texto usando openssl se usa el comando openssl pkeyutl con la opción -encrypt.

❯ openssl pkeyutl -encrypt -in fichero.txt -out fichero.txt.enc -inkey clav_public_raulhr.pem -pubin

Para descifrar el fichero de texto del compañero se usa el comando openssl pkeyutl con la opción -decrypt

❯ openssl pkeyutl -decrypt -inkey javi_huete.pem -in pikachu.bin -out pikachu.txt

Al leer el fichero se puede acceder a su contenido.

❯ cat pikachu.txt 
pokemon
comments powered by Disqus

Relacionados

Autentificación SSH con cifrado asimétrico usando GPG

Para que la conexión entre cliente y servidor por SSH sea más ágil y rápida, se usa un cifrado simétrico. Sin embargo, para que una conexión con cifrado simétrico sea segura es necesario que ambos interlocutores negocien una clave simétrica usando una conexión segura.

Leer

Creación de una VPN punto a punto con IPSec

Este escenario está formado por dos routers Cisco c7200 que comparten una red. Por la otra interfaz, cada uno cuenta con una red privada. Usando el protocolo IPSec se crea un túnel entre ambos routers que permita comunicar las dos redes privadas a través de una VPN.

Leer

Instalación y configuración de un servidor de correos de Internet

Para configurar un servidor de correos en un servidor expuesto a Internet hay que instalar un servicio SMTP en este servidor. En este caso, se usa el servidor postfix.

Leer