82

Cómo firmar y verificar tus commits con una llave GPG

7178Puntos

hace 3 años

Una llave GPG es una herramienta de cifrado y firmas digitales desarrollado por Werner Koch es software libre y es la herramienta que nos permite firmar los commits, la cual es la manera de mostrar a los otros compañeros de equipo que tú fuiste la persona que hizo el commit.

Si quieres ver la versión en Inglés de este post ve a: Sign commits with a GPG Key

Si no sabes, Git tiene la opción de poner tu correo electrónico y tu nombre en la configuración, imagínate que otra persona de equipo utiliza tu correo electrónico y tu nombre y sube el código que tú no hiciste con tu nombre. Este es el tema que quiero proteger.

Untitled.png

GitHub y GitLab tienen una forma de mostrar si el commit tiene la firma que ya has creado en tu cuenta, en la lista de commits de GitHub puedes ver la etiqueta “verified”.

Puedes hacer clic en esa etiqueta para obtener más información, como el ID de la clave GPG y el nombre de usuario, el nombre de un avatar del usuario que hizo el commit.

Para obtener más información sobre los estados de verificación, visite la página de gestión de la verificación de firmas. (En inglés) https://docs.github.com/en/authentication/managing-commit-signature-verification/displaying-verification-statuses-for-all-of-your-commits#about-vigilant-mode


Como firmar un commit

Son cuatro pasos para lograrlo:

  1. Instalación de requisitos.
  2. Generar una clave GPG.
  3. Configurar git y GitHub para usar la clave generada en el paso anterior.
  4. Haz un commit firmado.

Instalación de requisitos

Para firmar los commits puedes instalar estas tres herramientas: gpg2 gnupg pinentry-mac (yo uso brew para instalar las herramientas en mi Mac, si quieres instalar brew escribí un artículo: Cómo instalar Brew), aquí está el comando:

brew install gpg2 gnupg pinentry-mac

Después de la instalación tienes que configurar las herramientas, te daré un conjunto de comandos que son necesarios para que gpg2 funcione en macOS:

mkdir ~/.gnupg
echo'pinentry-program $(brew --prefix)/bin/pinentry-mac' > ~/.gnupg/gpg-agent.conf
echo'use-agent' > ~/.gnupg/gpg.conf

Si usas zsh necesitas ejecutar:

echo"export GPG_TTY=\$(tty)" | cat - ~/.zshrc | tee ~/.zshrc

Eso es todo, reinicie su terminal para seguir los siguientes pasos.

Generar una clave GPG

Una vez hecho el paso anterior, estás listo para ejecutar el comando para generar la clave gpg. El comando es --full-gen-key la siguiente es la salida del comando, esta es una forma interactiva de generar, por lo que te daré las opciones que utilicé, en tu caso por favor usa tus datos personales:

gpg --full-gen-key
gpg (GnuPG) 2.3.3; 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.
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? 4 **<----— Esta fue la respuesta**
RSA keys may be between 1024 and 4096 bits long.
What keysize do you want? (3072) 4096 **<----— Esta fue la respuesta**
Requested keysize is 4096 bits
Please specify how long the key should be valid.
         0 = key does not expire
        = key expires in n days
      w = key expires in n weeks
      m = key expires in n months
      y = key expires in n years
Key is valid for? (0) 0 **<----— Esta fue la respuesta**
Key does not expire at all
Is this correct? (y/N) y <----— Esta fue la respuesta
GnuPG needs to construct a user ID to identify your key.
Real name: You Name **<----— Esta fue la respuesta**
Email address: [email protected] **<----— Esta fue la respuesta**
Comment: You may add info here **<----— Esta fue la respuesta**
You selected this USER-ID:
    "You Name (You may add info here) "
Change (N)ame, (C)omment, (E)mail or (O)kay/(Q)uit? O <----— Esta fue la respuesta
We need to generate a lot of random bytes. It is a good idea to perform
some other action (type on the keyboard, move the mouse, utilize the
disks) during the prime generation; this gives the random number
generator a better chance to gain enough entropy.
gpg: key A977A899DB52BB49 marked as ultimately trusted
gpg: directory '/Users/lcmartinez/.gnupg/openpgp-revocs.d' created
gpg: revocation certificate stored as '/Users/lcmartinez/.gnupg/openpgp-revocs.d/CE183E0DB30E37355A1DD05DA977A899DB52BB49.rev'
public and secret key created and signed.
Note that this key cannot be used for encryption.  You may want to use
the command"--edit-key" to generate a subkey for this purpose.
pub   rsa4096 2021-11-12 [SC]
      CE183E0DB30E37355A1DD05DA977A899DB52BB49
uid                      You Name (You may add info here) In this question, you may answer (4) RSA (sign only)

Para comprobar si ya tienes una llave puedes ejecutar:

gpg -k

Configurar git y GitHub para utilizar la clave generada en el paso anterior

Obtenga su id de clave ejecutando el siguiente comando, en mi caso el id de mi llave gpg es: DB52BB49

gpg -K --keyid-format SHORT
# Salida:
/Users/lcmartinez/.gnupg/pubring.kbx
------------------------------------
sec   rsa4096/***DB52BB49*** 2021-11-12 [SC]
      CE183E0DB30E37355A1DD05DA977A899DB52BB49
uid         [ultimate] You Name (You may add info here) 

Necesitamos este ID para generar un BLOQUE DE CLAVE PÚBLICA PGP, para generarlo se debe ejecutar el siguiente comando:

gpg --armor --export ***DB52BB49*** # <--- El id del paso previo# Salida
-----BEGIN PGP PUBLIC KEY BLOCK-----
mQINBGGOuIYBEADMIGGiPLZXXbi64qGWnA/Lc37kXZzS4iNRXAEKLGz2IJPHLGyJ
OJt8alEDD585jmhwKcvwoHzGIEXfRsG07mqp7/MOCAzHhOo03Ykh6QG6RL1y2LeJ
YhIi4IHlE4vjfyoPrs2ota6n6ZtaA+3MP8X+K2zIXXU7SjdH893SaoxLwYEt1ssX
l9OqNNgvcqiBVqH/ZEFcB0+q7M01SjyBpGZ3AV0px3gRwmc0RzJeYdVVoISD1A6A
x4+TLwatjLcUox7KQWiLG7o2K1qtyWFZVWW/0K4XBuOPRL6/hDpXXbCrB5OGuZ10
hNa9ESa2KsHEJzclBuj++BwR2m37sS6BzbltS45a++5eXm53K61xOHDbM4oz414T
MJRUIK3JuG7bue2Be9oLfMQLDOWrZTokkNjdpBeHVznGJ6DkfIJ59J5/QR84fIPf
xz4/39DK/xP/b9+4m/9RCpJOw54DJPt+qOB3siUvNQWZr4E8ktXJsabE/33gd4iE
ithz37anawLJNXmlfnC8CyH6HAf/nadzXM28HB6MKaFE81xvaVPkNcFdLMT7PZIX
zgqgzNZ4ncuSV3TM9x6ygoDP+DTlilNTsBOcLv68v5qlXQIxo3TE3WCVExoaq5AN
TUlSML3iD7rPulGTNVtxvABPkyfD+1IwYg2B/IjpjAoDb2wAFH6OfpCvBQARAQAB
tDlZb3UgTmFtZSAoWW91IG1heSBhZGQgaW5mbyBoZXJlKSA8eW91ci1lbWFpbEBh
ZGRyZXNzLmNvbT6JAlIEEwEIADwWIQTOGD4Nsw43NVod0F2pd6iZ21K7SQUCYY64
hgIbAwULCQgHAgMiAgEGFQoJCAsCBBYCAwECHgcCF4AACgkQqXeomdtSu0kPzQ/8
Ck8h9YOhgF7GE4HCI8eOXAMrcKzA3MGQemFuWRSaHxFdKcJ4RyJAOlatFvI/99ZR
ReQKXzBSNrMMYcyiUdpxlYf6CykrcAR4gbJzMQHB7X9ARekNTkMNMhrgPbdUILz4
AG2JVl9+QbgnX0BlhacyKtL+6jDrawPoM6a0TB6UKqNNSI+BQgymil+OByDTp0eg
QTE4QDx+gy+BkkgHumprxHcTw0oNzKRX8oRlJnlUCbsramv3T9lP1gNSiFcYvHnD
gpi7IL2FZ1ssVGH4fDLu04yKV519mJEDTzlebMZBi+vHVCEsFbuzDAcpdCOTwt//
cEJnvk1oRoqi+RF9GvMLABt545epwFo0c/yGEfJtA62QPAGQkpICPVD6YpipYOQi
Ngc/rn0bg/QAsmeDRCkl2m6DwbCHZf/iwN11hiM1ZM6oWRKg0ZuC0sVOyaSZgQVJ
AN/MF7aC7GnBqVuXn+tF+CHqQkHnlH68Ym1QKAiqG3GVc+Q5870TRAKElR56Vejw
Qc+6Is0q5Ayt3j7ElcanQzDB/6aNBvB+rLMZXTf/3ZrFY70XbxUiWnxPoUdL3h9U
wy4LTv2CXxeIKaLPCv1yTmc3IhbzyKLWszYCQAQCUmcRVngpuKJrS+UcS0VMsTqO
SBydddSzRMINhcZZMhUt5dHdV/bbZ13HrA5vAHkMvXY=
=Xy9r
-----END PGP PUBLIC KEY BLOCK-----

Copiar la salida, luego agregarla a GitHub en:
Configuración > Claves SSH y GPG > Nueva clave GPG > Clave

El paso a paso con imágenes se puede encontrar en: Añadir una nueva clave GPG a tu cuenta de GitHub (documentación de GitHub En inglés)

Para configurar la herramienta de línea de comandos (git) en su máquina, puede ejecutar:

git config --global gpg.program $(which gpg)
git config --global user.signingkey DB52BB49 # Usa tu propio ID acá

Recuerde que esto es una demostración, POR FAVOR NO USE LA LLAVE DE ESTE POST. Genera una por ti mismo.

Haz un commit firmado

Hay dos opciones para firmar un commit, manualmente si sólo quieres firmar un commit específico con la bandera -S

git commit -S -m "Mi primer commit firmado"

Tal vez quieras firmar cada commit que hagas, así que puedes configurar git para que firme automáticamente los siguientes commits, para ello puedes configurar git con el siguiente comando:

git config --global commit.gpgsign true

Cada vez que firmes un commit te va a pedir la contraseña en un modal, puedes guardar la contraseña en el llavero si quieres o puedes escribir la contraseña.

Conclusión

En Platzi tenemos un curso de Git y GitHub en el que puedes aprender mucho más y aunque firmar tus commits no es obligatorio, es una buena manera de asegurarse de que el compromiso con las cosas de seguridad en el equipo existe. Por favor, hazlo, no solo para etiquetar los commits, sino para protegerte de que un mal compañero de equipo haga cosas malas con tu nombre.

Si te gustó este post, por favor hazme saber en los comentarios qué tipo de tema quieres aprender en el próximo post.

Luis
Luis
lcmartinez_

7178Puntos

hace 3 años

Todas sus entradas
Escribe tu comentario
+ 2
Ordenar por:
6
7250Puntos

¡Excelente post! Muchas gracias por la info.
No conocía nada de esto así que intenté configurarlo en mi PC donde estoy utilizando Manjaro (una distribución Linux basada en Arch Linux). Tuve unos problemas que pude solucionar, así que dejo los pasos generales que seguí.

Lo primero que hice fue instalar GPG / GnuPG:

  • En Arch Linux, en la consola usamos el comando pacman -S para instalar paquetes oficiales:
    pacman -S[nombre-del-paquete]
    Quizás necesites permisos de super usuario así que le agregamos el sudo, quedando:
    sudo pacman -Sgnupg

Luego solo seguí la documentación oficial:

Ahora bien, al querer hacer un commit obtenía lo siguiente:
error: gpg failed to sign the data
fatal: failed to write commit object

Por lo tanto no podía concretar el commit. Para solucionar mi problema encontré este post en Gist: Cómo entender el error gpg failed to sign the data en Git
La solución no vino de mano de la creadora del post paolacarrasco, sino del comentario de NirajanMahara:

Usamos el siguiente comando en la consola echo "test" | gpg --clearsign
Si obtienes:
-gpg: signing failed: Inappropriate ioctl for device
-gpg: [stdin]: clear-sign failed: Inappropriate ioctl for device

Entonces realizas lo siguiente:
export GPG_TTY=$(tty)

En mi caso, porque estoy utilizando una shell distinta (Fish), tuve que eliminar el signo de peso $
export GPG_TTY=(tty)

Vuelves a utilizar echo "test" | gpg --clearsign y, si obtienes algo como esto:
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA512

test
-----BEGIN PGP SIGNATURE-----

iLMEAQEKAB0WIQS2V0SFHi18psvDbo7uFF+LP7qc1gUCYLjB2QAKCRDuFF+LP7qc 1r5LBACB1m3Lpl21379qAvVamWcn9isdgdg34t34t43t34t34t434yGQHqikxWL7A5 Ls7giKZYscb30o0rkY6I1W9MjBBW96R2pnaYsioFpsf434dfg54rfdgfdgdfgdfpaIoU3k JKrYxR7yMjqUv0a2jE+97kh+bSuzqwIkMHyikbABI90lY+4OLw== =UHKx
-----END PGP SIGNATURE-----

Ya debería estar funcionando la firma para tus commits.

Espero para que los esten usando esta distribución, o tengan el mismo problema con otra, les funcione.

2
7178Puntos
3 años

¡Qué gran aporte!

Muchas gracias por compartir tu experiencia.

4
7250Puntos
3 años

De nada!

Ahora me encontré con que al querer hacer un commit nuevamente tenía el error:

gpg: signing failed: Inappropriate ioctl for device
gpg: [stdin]: clear-sign failed: Inappropriate ioctl for device

Así que pensé que tenía que hacer todo de nuevo…
Lo que sucede es que hay un problema con Fish shell.
Cuando vamos a firmar un commit se llama al GPG-AGENT que es un daemon para manejar llaves secretas (privadas) independientemente de cualquier protocolo.

Lo que hay que hacer es ir a la configuración de fish (debería estar en la carpeta fish y el archivo es config.fish)

cd ~/.config/fish/
vi config.fish

En mi caso, al instalar Fish se guardó en la carpeta .config en mi PC.
Uso el alias vi que creé para modificar el archivo con NeoVim y agregar la siguiente linea:

set -gx GPG_TTY (tty)

Y con eso pude volver a firmar normalmente el commit.

Solución para Fish encontrada en GPG no funciona con fish [inglés]
/
/
Si usan Bash no deberían tener este problema ya que en la documentación oficial que compartí (Comentandole a Git sobre nuestra firma), cuando añadimos la llave GPG a nuestro perfil bash usamos el siguiente comando:

if [ -r ~/.bash_profile ]; thenecho'export GPG_TTY=$(tty)' >> ~/.bash_profile; \
  elseecho'export GPG_TTY=$(tty)' >> ~/.profile; fi

Ahí se encuentra el export GPG_TTY=$(tty) que ya se guarda en bash, como lo hacemos manualmente para fish.

Espero que esta sea la solución definitiva para mi caso y el de las personas que también usen Linux con Fish shell jajajajaj

1
25741Puntos
2 años

Muchas gracias, estaba atorado en lo mismo que tu 😅

2
69721Puntos

Me encantó el post! Logré hacerlo en Ubuntu 20.04, la única diferencia fue que solo es necesario instalar gnupg. Luego directamente salté a generar la llave GPG.
Al generar la llave no se olviden tener una contraseña lista para su llave, esta clave se pide en todos los commits que hagan.
Luego seguí los pasos de Luis y listo. Me encanta lo profesional que se ve.
Captura de pantalla de 2022-01-06 18-09-49.png

1

Esto iniciará un proceso interactivo para configurar tu nueva llave GPG. Sigue las instrucciones en pantalla, que incluirán elegir el tipo de clave (generalmente RSA o RSA y RSA), la longitud de la clave (recomendado 2048 bits o más)

1

To sign commits using GPG and have those commits verified on GitHub, follow these steps:
Check for existing GPG keys.
Generate a new GPG key.
Add a GPG key to your GitHub account.
Tell Git about your signing key.
Sign commits.
Sign tags.
auto clicker

1
25741Puntos

Muchas gracias por la info 🤯. Llevaba semanas buscando algo que me ayudará a lograrlo 🥳

1
27949Puntos

Sería bueno un tutorial de cómo firmar los commits usando PowerShell, ya que he intentado varias veces, pero no ha sido posible que funcione correctamente

1

Hi Luis, Thanks for sharing such an wonderful blog and start writing more informative blog. I will follow you.

Regards,
Prapti
Website

1
27871Puntos

Muchas gracias por la info !

Que pro se ven mis commits ahora jajaja
Screenshot 2022-01-03 231932.png

1
7178Puntos
3 años

Genial que hayas seguido todos los pasos, cuéntame qué más quieres aprender en este tipo de posts.

1
11252Puntos

Buena explicacion pero una duda alguien mepodria decir ventajas o desventas de tenerlo firmado o no?

1
7178Puntos
3 años

Ventajas:

  • Tu equipo de trabajo va a estar completamente seguro que los cambios que se suben al repositorio por ti los hiciste tú mismo y no otra persona que se hizo pasar por ti.
  • Brindas seguridad al equipo de trabajo

Desventajas

  • Dependiendo de la configuración puede que tengas que digitar la contraseña de la llave cada que quieras hacer un commit.
  • Si pierdes tu llave todos los commits previamente firmados aparecerán como “Firma no disponible”
1
410Puntos

muy buen post, gracias por la información.