1 Cifrado simétrico y asimétrico con GPG

GPG (GNU Privacy Guard) es una herramienta de cifrado de código abierto que implementa el estándar OpenPGP. Esta herramienta permite cifrar y firmar datos, proporcionando confidencialidad, integridad y autenticación.

En este tutorial, vamos a aprender a realizar cifrado simétrico y cifrado asimétrico utilizando GPG.

1.1 Cifrado simétrico con GPG

1.1.1 Cifrado simétrico con GPG (Formato binario)

En primer lugar vamos a crear un archivo de texto sencillo para hacer experimentos con cifrado simétrico utilizando GPG.

echo "Hola mundo" > archivo.txt

Para realizar un cifrado simétrico con GPG puede utilizar los argumentos --symmetric o -c. Ambos comandos le solicitarán una contraseña para proteger el archivo cifrado.

gpg -c archivo.txt
gpg --symmetric archivo.txt

Los dos comandos son equivalentes y ambos crearán un archivo cifrado en formato binario, llamado archivo.txt.gpg.

Podemos ejecutar el comando file para verificar el tipo de archivo generado:

file archivo.txt.gpg

Obtendremos una salida similar a la siguiente:

archivo.txt.gpg: PGP symmetric key encrypted data - AES with 256-bit key salted & iterated - SHA512 .

1.1.2 Cifrado simétrico con GPG (Formato ASCII Armor)

Para obtener un archivo cifrado en formato ASCII Armor con texto legible codificado en Base64, podemos añadir el argumento --armor.

gpg -c --armor archivo.txt
gpg --symmetric --armor archivo.txt

Los dos comandos son equivalentes y ambos crearán un archivo de texto en formato ASCII Armor, llamado archivo.txt.asc.

Durante el proceso de cifrado, GPG nos solicitará una contraseña para proteger el archivo cifrado.


1.1.3 Descifrado de un archivo cifrado con GPG

Para descifrar un archivo cifrado con GPG, independientemente de si es binario o en formato ASCII Armor, se utilizan los argumentos --decrypt o -d.

gpg -d archivo.txt.asc
gpg --decrypt archivo.txt.asc

El comando anterior mostrará el contenido descifrado en la terminal.

gpg: AES256.CFB encrypted data
gpg: encrypted with 1 passphrase
Hola mundo

¿Por qué GPG no me pide la contraseña?

Puede ocurrir que GPG no le haya solicitado la contraseña porque el agente de gestión de claves, gpg-agent, la tiene almacenada en caché en memoria. Esto se realiza de forma automática cuando se ha utilizado la contraseña de forma reciente para cifrar o descifrar. La contraseña se mantiene en caché durante unos minutos, pasado este tiempo se elimina automáticamente.

Para eliminar la contraseña de la caché de gpg-agent y forzar que se le solicite en la siguiente operación, puede utilizar el siguiente comando:

gpg-connect-agent KILLAGENT /bye

Podemos guardar el contenido descifrado en un archivo utilizando el argumento --output o -o.

gpg --decrypt --output archivo_descifrado.txt archivo.txt.asc

También podemos redirigir la salida estándar a un archivo utilizando el operador >.

gpg --decrypt archivo.txt.asc > archivo_descifrado.txt

1.1.4 Cifrado simétrico indicando el algoritmo

GPG utiliza por defecto el algoritmo AES-256 para el cifrado simétrico. Sin embargo, es posible especificar un algoritmo diferente utilizando el argumento --cipher-algo seguido del nombre del algoritmo deseado.

Para consultar cuál es la lista de algoritmos soportados por GPG, podemos utilizar el siguiente comando:

gpg --version

Nos devolverá una salida similar a la siguiente:

gpg (GnuPG) 2.4.4
libgcrypt 1.10.3
Copyright (C) 2024 g10 Code GmbH
License GNU GPL-3.0-or-later <https://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

Home: /home/josejuan/.gnupg
Supported algorithms:
Pubkey: RSA, ELG, DSA, ECDH, ECDSA, EDDSA
Cipher: IDEA, 3DES, CAST5, BLOWFISH, AES, AES192, AES256, TWOFISH,
        CAMELLIA128, CAMELLIA192, CAMELLIA256
Hash: SHA1, RIPEMD160, SHA256, SHA384, SHA512, SHA224
Compression: Uncompressed, ZIP, ZLIB, BZIP2

También podemos utilizar el argumento --help:

gpg --help

Si quisiéramos cifrar un archivo utilizando el algoritmo AES-192, podríamos hacerlo de la siguiente manera:

gpg -c --cipher-algo AES192 archivo.txt

1.2 Cifrado asimétrico con GPG

1.2.1 Generación de un par de claves

Para generar un par de claves, pública y privada, con GPG, utilizamos el siguiente comando:

gpg --full-generate-key

Este comando nos guiará a través de una serie de preguntas para configurar nuestro par de claves.

gpg (GnuPG) 2.4.4; Copyright (C) 2024 g10 Code GmbH
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

Please select what kind of key you want:
   (1) RSA and RSA
   (2) DSA and Elgamal
   (3) DSA (sign only)
   (4) RSA (sign only)
   (9) ECC (sign and encrypt) *default*
  (10) ECC (sign only)
  (14) Existing key from card
Your selection? 

En primer lugar, nos pregunta qué algoritmo de cifrado queremos utilizar. Por defecto, nos recomienda utilizar un algoritmo Elliptic Curve Cryptography que sirve tanto para firmar como para cifrar.

RSA vs ECC (Elliptic Curve Cryptography)

RSA
- Se basa en la dificultad de factorizar números primos muy grandes.
- Es lento para firmar y rápido para verificar.
- Utiliza claves muy grandes.

ECC
- Se basa en el problema del logaritmo discreto en curvas elípticas.
- Es rápido tanto para firmar como verificar. Es más eficiente en dispositivos móviles y hardware limitado.
- Utiliza claves más pequeñas que RSA.


1.2.2 Obtener un listado de claves públicas

Para obtener un listado de las claves públicas que tenemos en nuestro equipo podemos utilizar este comando:

gpg --list-keys

La salida del comando nos devolverá algo similar a esto:

/home/ubuntu/.gnupg/pubring.kbx
-------------------------------
pub   ed25519 2025-11-18 [SC]
      8B14202871E9D29CE2C8A0FFD4619A5D5B073B30
uid           [ultimate] José Juan <midireccion@iescelia.org>
sub   cv25519 2025-11-18 [E]

pub   rsa3072 2025-11-18 [SC]
      BF61B927FE8CBA8745AEC6BDDECF4A4E44DDD318
uid           [ultimate] JJ <jj@iescelia.org>
sub   rsa3072 2025-11-18 [E]

El campo pub indica la clave pública, mientras que el campo sub indica la clave secundaria asociada a la clave pública. Junto a estos campos se muestra el tipo de algoritmo que se ha utilizado.

El campo uid identifica al propietario de la clave, mostrando el nombre y el correo electrónico asociado.

Las letras entre corchetes significan los usos permitidos para cada clave:


1.2.3 Obtener un listado de claves privadas

Para obtener un listado con las claves privadas que tenemos en nuestro equipo podemos ejecutar:

gpg --list-secret-keys 

1.2.4 Exportar una clave pública

Para exportar una clave pública utilizamos el argumento --export. También será necesario indicar el nombre o el correo electrónico asociado a la clave pública que queremos exportar.

Si no indicamos lo contrario, la clave se exportará por defecto en formato binario.

gpg --export midireccion@iescelia.org > clave_publica.gpg

Para exportarla en formato ASCII Armor codificado en Base64, utilizamos el argumento --armor.

gpg --export --armor midireccion@iescelia.org > clave_publica.asc

1.2.5 Exportar una clave privada

Para exportar una clave privada utilizamos el argumento --export-secret-keys. También será necesario indicar el nombre o el correo electrónico asociado a la clave pública que queremos exportar.

Si no indicamos lo contrario, la clave se exportará por defecto en formato binario.

gpg --export-secret-keys midireccion@iescelia.org > clave_privada.gpg

Para exportarla en formato ASCII Armor codificado en Base64, utilizamos el argumento --armor.

gpg --export-secret-keys --armor midireccion@iescelia.org > clave_privada.asc

En ambos casos, nos solicitará la contraseña asociada a la clave privada para autorizar la exportación.


1.2.6 Importar la clave pública de otra persona

Para importar la clave pública de otra persona utilizamos el argumento --import seguido del nombre del archivo que contiene la clave pública.

gpg --import clave_de_otra_persona.asc

Para comprobar que la clave se ha importado de forma correcta podemos ejecutar este comando:

gpg --list-keys

1.3 Cifrar un archivo para otra persona

Para cifrar un archivo utilizando la clave pública de otra persona, utilizamos el argumento --encrypt junto con --recipient, seguido del nombre o correo electrónico asociado a la clave pública de la persona a la que queremos enviar el archivo cifrado.

gpg --encrypt --recipient <USER_ID_DESTINATARIO> <NOMBRE_ARCHIVO>

Ejemplo para cifrar un archivo en binario:

gpg --encrypt --armor --recipient destinatario@iescelia.org archivo.txt

Este comando creará un archivo cifrado con extensión .gpg con el contenido en binario.

Ejemplo para cifrar un archivo en Base64:

Si le añadimos el argumeno --armor se creará un archivo con extensión .asc y el contenido del archivo cifrado estará en Base64.

gpg --encrypt --armor --recipient destinatario@iescelia.org archivo.txt

1.3.1 Descifrar un archivo que ha sido cifrado con nuesra clave pública

Para descifrar un archivo que ha sido cifrado con nuestra clave pública, utilizamos el argumento --decrypt seguido del nombre del archivo cifrado.

gpg --decrypt archivo.txt.gpg > archivo.txt

1.3.2 Firmar un archivo

Existen dos formas de firmar un archivo con GPG:

Ejemplo de firma desvinculada.

Se utiliza el argumento --detach-sign.

gpg --detach-sign archivo.txt

Ejemplo de firma incluida en el mismo archivo.

Se utiliza el argumento --sign.

gpg --sign archivo.txt

Nota

Si tuviéramos varias identidades en nuestro llavero de GPG, podríamos especificar cuál utilizar con el argumento -u o --local-user, seguido del nombre o correo electrónico asociado a la clave privada que queremos utilizar para firmar. Ejemplo:

gpg --sign -u midreccion@iescelia.org archivo.txt

1.3.3 Verificar la firma de otra persona

Para verificar la firma de un archivo firmado por otra persona, utilizamos el argumento --verify seguido del nombre del archivo de la firma y del archivo original.

gpg --verify archivo.txt.sig archivo.txt

1.4 Referencias