Cifrado asimétrico con GPG y OpenSSL
- Javi Huete
- Seguridad
- January 14, 2025
Í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