Cifrando y firmando con gpg

Introducción

Con los objetivos cada vez más evidentes de organizaciones nacionales y supra-nacionales de censurar y limitar el discurso público*, considero sumamente importante que las personas corrientes dispongamos de herramientas que nos permitan llevar a cabo comunicaciones privadas fuera del alcance de las buenas intenciones de estas entidades.

Así, este artículo pretende ser una breve y comprensiva introducción a la herramienta gpg (GnuPG), que permite hacer uso de sistemas de criptografía simétrica (de clave secreta) y asímetrica (de clave pública) para cifrar y firmar ficheros digitales.


* Ver los artículos:

Criptografía simétrica (de clave secreta)

Cifrado

Cifrar (o encriptar) consiste en transformar un mensaje de tal forma que sólo sea legible para quienes tengan la clave de descifrado.

El cifrado con criptografía simétrica consiste en utilizar (normalmente) una contraseña para cifrar y descifrar un mensaje. Si tenemos un fichero llamado "mensaje"

$ cat mensaje               
Esto es un mensaje

podemos cifrarlo así:

$ gpg -c --armor mensaje

Esta instrucción solitará una clave (contraseña) al usuario para cifrar el fichero.

Lo que resulta de la instrucción anterior es un fichero llamado "mensaje.asc" que contiene el mensaje cifrado:

$ cat mensaje.asc 
-----BEGIN PGP MESSAGE-----

jA0EBwMCnfzpeh2ngNv/0koBH2l9qXUxSbvRoPAy3uNpRNnVP/MIbxjXfv336SCM
U/mUmbYgGQ/ZIINkUE1xXz1JLDz8iJnt6k6Tj/asF8rVBafccpmY0f8DRw==
=UpUo
-----END PGP MESSAGE-----

Se puede prescindir de la opción "--armor", lo que resultaría en un fichero binario (que no contiene texto imprimible) cuyo contenido no podría mostrarte.

Descifrado

Descifrar (o desencriptar) consiste en utilizar una clave de descifrado para hacer legible un mensaje cifrado.

Alguien que tuviera el fichero "mensaje.asc" anterior y la clave secreta (contraseña) con la que se cifró podría descifrarlo haciendo

$ gpg -d mensaje.asc

lo que le solicitaría al usuario la clave de cifrado. Que tras introducirla obtendría

gpg: AES.CFB encrypted data
gpg: encrypted with 1 passphrase
Esto es un mensaje

Tambíen se podría usar la opción "--output" para guardar en un fichero el mensaje descrifrado

$ gpg --output descifrado -d mensaje.asc
gpg: AES.CFB encrypted data
gpg: encrypted with 1 passphrase

$ cat descifrado 
Esto es un mensaje

Criptografía asimétrica (de clave pública)

Las claves

La criptografía asimétrica utiliza dos claves que se generan a la vez: la pública y la privada. La clave pública puede tenerla cualquiera, mientras que la privada debe mantenerse segura y en secreto. La clave pública se utliza para cifrar mensajes que sólo serán descifrables por la clave privada. La clave privada, además, se utiliza para firmar digitalmente, de forma que cualquiera que tenga la clave pública asociada puede comprobar la firma.

Generar el par de claves

Para generar un par de claves se puede usar la instrucción

$ gpg --quick-gen-key prueba@correo.com

que generará un par de claves asociados al usuario "prueba@correo.com" con la configuración por defecto (claves RSA de 3072 bits y con una caducidad de dos años).

Para un control más preciso de los parámetros de las claves se puede usar la opción "--full-gen-key" en vez de "--quick-gen-key"

Exportar la clave pública

Para que alguien pueda enviarte un mensaje que sólo tu clave privada pueda descifrar debe tener la clave pública asociada. Para ello, debes primero exportar tu clave pública:

$ gpg --export --armor prueba@correo.com > clavePublica

Esta instrucción generará el fichero de texto "clavePublica" con la clave pública de "prueba@correo.com", que contendrá algo como lo siguiente:

$ cat clavePublica 
-----BEGIN PGP PUBLIC KEY BLOCK-----

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
zh7j
=LnpL
-----END PGP PUBLIC KEY BLOCK-----

También se podría haber prescindido de la opción "--armor" al exportar la clave, lo que habría resultado en un fichero binario que cumpliría el mismo objetivo.

Ahora puedes compartir y hacer público el fichero "clavePublica" para que otros puedan importar tu clave pública y así poder enviarte mensajes cifrados y poder comprobar tus firmas digitales.

Importar una clave pública

Para cifrar ficheros dirigidos a alguien (a una clave privada) o para comprobar firmas hechas por una clave privada debes tener la clave pública asociada. Si obtienes un fichero que contiene una clave pública como "clavePublica" del apartado anterior, lo puedes importar así:

$ gpg --import clavePublica

Ahora puedes cifrar mensajes para la clave privada asociada y comprobar firmas hechas por esa clave.

Cifrado

Para cifrar un fichero dirigido al dueño de una clave privada, podemos hacer

$ gpg -r prueba@correo.com -e mensaje

lo que resultará en un fichero binario llamado "mensaje.gpg" que contendrá el mensaje cifrado.

Podríamos haber usado la opción "--output" para especificar un fichero de salida y/o la opción "--armor" para generar un fichero de texto:

$ gpg --armor --output cifrado -r prueba@correo.com -e mensaje

$ cat cifrado     
-----BEGIN PGP MESSAGE-----

hQGMA7mPDGaqUjRjAQv/T70PxKyRnXh7WspejRpNen2+SWjA1GLcFN/wbkBZqGIZ
Zn9BFG4bGokVat3HfQNqpsTbDlLOl8aYAm5BR9x+3tTTREjPaHOWIYyy4+es9IUk
EIwqAZ9FOQkipMQpTBGkJa+m14GucTPWtuvO02h6iNxac6uDi9l9+8T2BaKKo1Pn
Z4SqdYP5Sgjq6KQz+DIDX2LRJgTh0xQI4dTDoSX1K5O2GDLNL0kKs8v3vCi0grz4
/J7Fk/vXBQD3swnbjChEoFcKD0qW6KzHjECz0sFe/1ShqcmpYFcYbSvJF2wNnQB2
KAtqOxzuEaHaVwRqNScP+dSIWc4O0XH9Q1dGBAnZHoZt+jV1F5+Zg6hS6H9rwkFI
+S6X5yPFn4H3+HovFlJbslIosIp1+9cx4llJKXJme25HBNwYr8BXPlE7g5FbZ72T
poGwkTkbNUOc6CQy1ubiTbmCPTqE0OyUefZG3pSqQR7jlp5SQEMDfHndGEyPEg/M
nFWLs9tbOMOY+yqnwqkA0lABaqJ10dnv2qlOVeZQGqsMiyo2VaKH7/KquOgTRZW8
YmAP9q0ECOnqO2kviBRvcwef9MdrinI2AR7RwKqr2mbqaxmenlnACccAo1wmrTn8
8Q==
=etbB
-----END PGP MESSAGE-----

Descifrado

Para descifrar un mensaje se necesita la clave privada asociada a la clave pública que lo cifró. Si tenemos dicha clave privada podemos ejecutar

$ gpg -d mensaje.gpg 

lo que nos solicitará la contraseña que protege la clave privada (si la hubiera), y que nos dará como resultado

gpg: encrypted with 3072-bit RSA key, ID B98F0C66AA523463, created 2023-07-01
      "prueba@correo.com"
Esto es un mensaje

Al igual que antes, se puede usar la opción "--output" para especificar un fichero de salida para el texto descifrado.

Firmas digitales

Las claves de la criptografía asimétrica también se pueden usar para firmar y comprobar firmas (aunque no todos los algoritmos de claves lo permiten).

Firmar

Las firmas digitales son (a efectos prácticos) imposibles de falsficar, por lo que se asegura que la firma sólo pudo ser hecha por quien posee la clave privada. Si alguien tiene tu clave privada puede firmar igual que tú.

Si tenemos configurada una clave por defecto podemos firmar con ella simplemente haciendo

$ gpg -s mensaje

Para firmar un fichero como el usuario "prueba@correo.com" (con su clave privada) podemos ejecutar

$ gpg --local-user prueba@correo.com -s mensaje

Podríamos haber usado la opción "--output" para especificar un fichero de salida y/o la opción "--armor" para generar un fichero de texto:

$ gpg --local-user prueba@correo.com --armor --output firmado -s mensaje

$ cat firmado   
-----BEGIN PGP MESSAGE-----

owEB+gEF/pANAwAIAUNZnnaOVvf6AawgYgdtZW5zYWplZKBiAEVzdG8gZXMgdW4g
bWVuc2FqZQqJAcYEAAEIADAWIQQrHhntpAM5mCNUPABDWZ52jlb3+gUCZKBiABIc
cHJ1ZWJhQGNvcnJlby5jb20ACgkQQ1medo5W9/pYSAwAuhwCYlqIlFIgjpbhfXHT
oKB/p8QB2BWFvYh3YRTKeawFMvIzU6Vf/pa5Fs3hbqfMN0Yk6lb4gAd+D1SI/2Sl
jOU0seQvedz6JlO3MtUkb+ztV14W+CpJMhAf1PS+KTj5w1p2LXc/GZhejwbVb+gs
oCqjKl2OK7v2H3EcOJBH2YnguW60orzyvOPRrSITiDbqziXUMCtaUv1W0sXVl6qU
Dsx06x1T8KmS/7Pq+RcwLWyswGgFwlRBqfd3VupOFsEKF8hZ0jlIsjCQcBwsHF8i
4x8VmnBgiFS/XK3w22ymqCoHW+8XO68SinbBsJ03TvL22bKW/n3lJz5iMIs5tvxE
nfDQYD40EQVjmvq02zb9/pPSXNICmmp7j/liIE5qDQqgxUz5ItDiY+JunCg4v0Rq
HyJmzC5aRzqxF9eJ/yZF2rMrnJ6ZimO+Ro2FVXfB5kCbF114Q77etFDu9TFP/XfK
rAN8muSlZEI0M/pfkwH5cv+mEXv928IwlsIvugGe6FRl
=m0P0
-----END PGP MESSAGE-----

Esta firma contiene el propio mensaje firmado, de forma que alguien que tenga la clave pública puede comprobar la autenticidad de la firma y "recuperar" el mensaje firmado (esto lo veremos más adelante).


Otra forma de firmar es con una "firma separada" ("detached signature"), que requiere disponer del mensaje/fichero original junto con su firma para poder hacer la comprobación. Se puede hacer este tipo de firma de la siguiente forma:

$ gpg --detach-sign mensaje

Esta instrucción creará un fichero binario llamado "mensaje.sig" que contendrá la firma. Para generar una "firma separada" en un fichero de texto se puede usar la opción "--armor" (que generará un fichero ".asc"). Al igual que antes, se puede usar la opción "--output" para establecer el nombre del fichero de salida.


La última opción de firma que exploraremos será la firma "en claro" ("clear signature") que junta en un único fichero de texto el mensaje y su firma. Para firmar así, debemos ejecutar:

$ gpg --clear-sign mensaje

Lo que genera el fichero "mensaje.asc"

$ cat mensaje.asc 
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA256

Esto es un mensaje
-----BEGIN PGP SIGNATURE-----

iQGzBAEBCAAdFiEEeymXj+r5nMdddpFHaCOogf6l+dEFAmSgZPYACgkQaCOogf6l
+dFu5AwAlJ6XYj5B7vyKsD41yxBIcyLLWORFHha057bJaB3sceF4+T/0vln4DjmF
nvSZavntIJD93Olfgmy3SQ/oJate2xikS7IUq1FHHa8WGe3R/vkglfMB55f0KAVl
mvOYtLPb2ct64O86fWqSNrhZy5iyLv5sLUrT7FT7JKZwBlLNaCKFrYEOv1HWedlX
AaCfasryrN4F+S7YgUrtWAp9LrXJywe9RluPhgSGbMgMvNK2siZNAUJ6quVdk+4l
CITtYtSBcZKZ2FiXlTmN+eiTGPS1p9el/QhIP1mFjEEUOyNzd1U8dvY3vc3EtTqP
WJ4z+y03L1wHqkPcvBaicwtKbsa9Qz/s4minAoppctiIvHnIpTToDmls8/XEQaPz
sd74J63chBa+Tw7ieJgSBMp5wbtu1Cw5Npv8JrM7H7EM9VErNKFTAcfT1rjKlOOm
VApSvkeqDNhHWEjHpkeAOkaWjkr3lucljWPVAaTtV/BcsqTHmFZ+sdzhJfxnWY+r
Yku23FRP
=J3De
-----END PGP SIGNATURE-----

Al igual que antes, se puede usar la opción "--output" para establecer el nombre del fichero de salida.

Estos son los usos más básico de firma digital con gpg. Evidentemente, gpg permite hacer cosas más interesantes y complejas que estas, como firmar y cifrar a la vez. Toda esta información se puede consultar fácilmente en el manual de gpg.

Comprobar una firma

Para comprobar una firma se necesita tener la clave pública asociada a la clave privada que se usó para hacer la firma.

Para comprobar una firma debemos ejecutar:

$ gpg --verify mensaje.gpg
gpg: Signature made Sat 01 Jul 2023 07:51:27 PM CEST
gpg:                using RSA key 2B1E19EDA403399823543C0043599E768E56F7FA
gpg:                issuer "prueba@correo.com"
gpg: Good signature from "prueba@correo.com" [ultimate]

Puede que esta salida sea distinta a la que tú obtienes porque estoy comprobando una firma hecha por una clave privada que ya tengo. Si más bien te aparece un mensaje como este

gpg: Signature made Mon 10 Apr 2023 02:38:08 PM CEST
gpg:                using RSA key 81AC591FE9C4B65C5806AFC3F0AF4D462A0BDF92
gpg: Good signature from "binaryFate <binaryfate@getmonero.org>" [unknown]
gpg: WARNING: This key is not certified with a trusted signature!
gpg:          There is no indication that the signature belongs to the owner.
Primary key fingerprint: 81AC 591F E9C4 B65C 5806  AFC3 F0AF 4D46 2A0B DF92

no debes preocuparte por el "WARNING" (que solo te está avisando de que no has registrado la clave pública como "realmente de quien dice ser"), lo importante es la línea

gpg: Good signature from ...

Que indica que la firma es correcta y que el mensaje no ha sido alterado.

Ahora que has comporobado la firma puedes "recuperar" el mensaje firmado usando

$ gpg --output correcto --verify mensaje.gpg

$ cat correcto
Esto es un mensaje

Si la firma que quieres comprobar es una "firma separada" ejecuta

$ gpg --verify mensaje.sig
gpg: Signature made Sat 01 Jul 2023 08:03:04 PM CEST
gpg:                using RSA key 2B1E19EDA403399823543C0043599E768E56F7FA
gpg:                issuer "prueba@correo.com"
gpg: Good signature from "prueba@correo.com" [ultimate]

Alternativamente, si tu mensaje está en un fichero con otro nombre, ejecuta

$ gpg --verify mensaje.sig fichero 

Si la firma que tienes es un fichero de texto (no binario) puede que tenga la extensión ".asc". En este caso, simplemente sustituye en las instrucciones anteriores "mensaje.sig" por el nombre de tu fichero con la firma.


La gracia de las firmas digitales está en que su comprobación falla si se altera el fichero. Si "mensaje" contenía

$ cat mensaje
Esto es un mensaje

y lo modifico para que contenga

$ cat mensaje
esto es un mensaje

y vuelvo a comprobar la firma, resulta que la firma ya no es correcta

$ gpg --verify mensaje.sig mensaje
gpg: Signature made Sat 01 Jul 2023 08:03:04 PM CEST
gpg:                using RSA key 2B1E19EDA403399823543C0043599E768E56F7FA
gpg:                issuer "prueba@correo.com"
gpg: BAD signature from "prueba@correo.com" [ultimate]

Si la firma que queremos comprobar es una "firma en claro" la podemos comprobar exactamente igual que en el caso anterior:

$ gpg --verify mensaje.asc
gpg: Signature made Sat 01 Jul 2023 08:12:37 PM CEST
gpg:                using RSA key 2B1E19EDA403399823543C0043599E768E56F7FA
gpg:                issuer "prueba@correo.com"
gpg: Good signature from "prueba@correo.com" [ultimate]

Y, al igual que antes, si modificamos el fichero original

$ cat mensaje.asc       
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA256

ESTO YA NO ES UN MENSAJE
-----BEGIN PGP SIGNATURE-----

iQHGBAEBCAAwFiEEKx4Z7aQDOZgjVDwAQ1medo5W9/oFAmSgbRQSHHBydWViYUBj
b3JyZW8uY29tAAoJEENZnnaOVvf67JAMAIHmDc2zoz8kyRkHybj9QningXPipDYj
QlDcy2zaOjTcRlMKvS7lWKIPXBoIKjNv2L0LwYx/VNELVBZcsmUzFPYHcyGLV0Kl
wNriB6QFrDpZT6i2NYlzIlxaIZuxPB5LUrUAx5Ht6IU62MJHaGxFhiOu0H+Se+fJ
XXJDwMYxougsRLe5QjEY3pn7LA8InlFHvWf5fu/v2ZbIwlmxayiktFHTdwZ//wqG
iA15mCJ7Zhd4QcomDzlrdod0bN+TVjpeTv1ZAfhy8sdv0zNIIi2AFJTMtF1TPKDx
LZry/E7vuXKkleHO5V5c1PqutfRn5oO/K4Z0jfLTyq6/3tBA06tjZgobEfygEo2x
L/VHLwY9Yh0sD0czRacrPLihhMh+qkYIuPR6XGjCs7bjyeFQIAAdHs13+ID/yplL
C8kB4eTdie2quX14iei+KH1B7S3/b9ibGURidT6EY3xoe2F+A82DqxCTML2nbJYK
uR53cDDkcM9R44apambUUwr395gOrcHnyA==
=jn5O
-----END PGP SIGNATURE-----

La firma ya no será válida

$ gpg --verify mensaje2.asc 
gpg: Signature made Sat 01 Jul 2023 08:14:44 PM CEST
gpg:                using RSA key 2B1E19EDA403399823543C0043599E768E56F7FA
gpg:                issuer "prueba@correo.com"
gpg: BAD signature from "prueba@correo.com" [ultimate]

Conclusión

En este artículo hemos explorado los usos más básicos de gpg para cifrar y firmar mensajes. gpg es una potente herramienta, fácil de usar y al alcance de todos. Aunque no será la solución a la distopía a la que inevitablemente parecemos dirigirnos, sí será un potente aliado en la lucha por la privacidad y la libertad en la esfera digital.

Nos vemos en la próxima, internauta.


Etiquetas:
Software   Guías   Técnico