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:
S: La clave puede ser utilizada para firmar (Sign).C: La clave puede ser utilizada para certificar otras claves (Certify).E: La clave puede ser utilizada para cifrar (Encrypt).
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:
- Firma desvinculada del archivo. La firma se guarda
en un archivo
.sigo.ascseparado del archivo original. Es la forma recomendada ya que permite mantener el archivo original intacto y distribuir la firma por separado. - Firma incluida en el mismo archivo. El archivo original se cifra y la firma se incluye dentro del archivo original.
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
-uo--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