← Blog

GPG — Cifrado, Firmas y Descifrado de Artefactos Incautados

OpenPGP con GnuPG: cifrado simétrico y asimétrico, gestión de claves, exportación/importación, descifrado de ficheros incautados y fundamento criptográfico de RSA.

1. Operational Scope & Technical Objective

gpg implementa el estándar OpenPGP sobre GnuPG: cifrado, firma y gestión de claves. Para un engagement, el interés es doble: descifrar artefactos incautados (ficheros .gpg/.p12 que protegen material sensible en el objetivo) y proteger el canal de exfiltración cifrando datos antes de transferirlos. A nivel conceptual, entender RSA —la exponenciación modular m^e mod n con n = pq— es lo que permite leer un pubring/private-keys-v1.d y saber exactamente qué puede y qué no puede abrir un atacante con una copia de las claves.

2. High-Impact Syntax & Command Cheatsheet

Entorno de laboratorio aislado

mkdir -p ~/gpg-lab && chmod 700 ~/gpg-lab
export GNUPGHOME=~/gpg-lab        # todo gpg de la sesión usa este directorio

Cifrado simétrico (una passphrase) y descifrado

echo "This is an encryption test" > file1.txt
gpg -c file1.txt                  # -c: cifrado simétrico; pide passphrase
file file1.txt.gpg                # "GPG symmetrically encrypted data"
mv file1.txt.gpg testfile01.doc   # renombrar no afecta al contenido
gpg -d testfile01.doc > recovered.txt   # -d/--decrypt: extrae el contenido
gpgconf --kill gpg-agent          # mata el agente para forzar el prompt de passphrase

Cifrado asimétrico (par público/privado)

gpg --full-generate-key           # RSA+RSA, 4096 bits recomendado; passphrase protege la privada

gpg --export -a "Nombre del Usuario" > mypublickey.asc   # -a: ASCII armor
gpg --import mypublickey.asc
gpg --list-keys

gpg --encrypt --recipient "test (test) <test@test.test>" message.txt
# genera message.txt.gpg; solo la clave privada correspondiente lo abre
gpg --decrypt message.txt.gpg > decrypted.txt

# Varios destinatarios: repetir --recipient por cada clave pública
gpg --encrypt --recipient "A" --recipient "B" -o out.gpg input.txt

Artefactos del keyring (qué encuentra un atacante en ~/.gnupg)

# private-keys-v1.d/  -> claves privadas, cifradas con la passphrase del usuario
# pubring.kbx        -> keyring de claves públicas (formato .kbx moderno)
# random_seed        -> entropía interna de GPG (no legible, no modificable)

Conceptos clave

  • Cifrado simétrico: una única passphrase compartida (-c).
  • Cifrado asimétrico: clave pública cifra, clave privada descifra.
  • Híbrido: cifrar con la clave pública del destinatario y proteger la clave privada con passphrase.
  • gpg-agent cachea la passphrase en memoria; gpgconf --kill gpg-agent la descarta.

3. Real-World Offensive/Defensive Scenarios

Descifrado de ficheros incautados en el objetivo. Un backup *.gpg o un *.p12 en el home del usuario suele contener credenciales o claves. Si se recupera la passphrase (keylog, ~/.bash_history, dump de gpg-agent) el descifrado es directo: gpg -d backup.gpg > backup. La copia de private-keys-v1.d/ sin la passphrase no sirve de nada, pero sí revela qué usuarios gestionan claves y con qué validez (datos de --list-keys para profiling).

Protección de datos extraídos. Antes de transferir material sensible (bases de datos, configs, credenciales), gpg -c con passphrase fuerte impide que la exfiltración sea leíble si se intercepta el canal — y hace el volcado indistinguible de un fichero legítimo del usuario comprometido.

Defensa. Monitoriza ~/.gnupg (permisos 700, auditoría de private-keys-v1.d/), rota las passphrases, y vigila la copia masiva de *.gpg/*.p12 en los accesos de red (firma de exfiltración de material cifrado).

Fundamento criptográfico: RSA y por qué "funciona"

Clásica vs. pública

La criptografía clásica (monoalfabética: shift y affine ciphers) sustituye carácter a carácter y cae ante análisis de frecuencia; agrupar bloques (block ciphers) lo mitiga. La criptografía de llave pública usa claves distintas para cifrar (pública) y descifrar (privada), resolviendo el intercambio seguro de la clave simétrica.

RSA

Cada usuario tiene una clave de cifrado (n, e) con n = pq (producto de dos primos grandes, 300 dígitos o más cada uno en la práctica). Para cifrar basta n y e; para descifrar se necesita la factorización de n en p y q, que es computacionalmente inviable con primos grandes.

Por qué se usa e: c = m^e mod n. Para que el esquema tenga inversa, e debe cumplir gcd(e, φ(n)) = 1, donde φ(n) = (p−1)(q−1) es la función totiente de Euler. El inverso modular d satisface e·d ≡ 1 (mod φ(n)) y es el exponente privado. Se suele usar e pequeño y fijo (65537) porque acelera el cifrado mientras cumpla esa coprimalidad.

Por qué aparece (p−1)(q−1): para n = pq con primos distintos, φ(pq) = φ(p)·φ(q) = (p−1)(q−1). El teorema de Euler garantiza m^{φ(n)} ≡ 1 (mod n) cuando gcd(m, n) = 1, y esa relación es la que hace que cifrar y descifrar sean operaciones inversas: (m^e)^d = m^{e·d} = m^{1 + k·φ(n)} ≡ m (mod n).

Generación de claves:

  1. Elegir dos primos grandes p, q.
  2. n = p·q.
  3. φ(n) = (p−1)(q−1).
  4. Elegir e con 1 < e < φ(n) y gcd(e, φ(n)) = 1.
  5. d = e^{-1} mod φ(n).
  6. Pública (n, e); privada (n, d).

Cifrado c = m^e mod n · Descifrado m = c^d mod n.

Mini-RSA didáctico (no seguro en la práctica)

Con p = 7, q = 11: n = 77, φ(n) = 60, e = 7 (coprimo con 60), d = 43 (porque 7·43 = 301 ≡ 1 mod 60). Mensaje m = 20: c = 20^7 mod 77 = 51; 51^43 mod 77 = 20. Pública (77, 7), privada (77, 43).

Bloqueo de 2N dígitos

Las letras se traducen a números de 2 dígitos (A=00…Z=25, o A=01…) y se agrupan en bloques de longitud par tales que el número del bloque sea siempre menor que n. Si un bloque ≥ n, la reducción módulo n colisiona y se pierde información. Ejemplo con n = 2537: "STOP" → 1819 1415 (bloques de 4 dígitos, porque 2525 < 2537 pero 252525 > 2537). Con pública (2537, 13): 1819^13 mod 2537 = 2081, 1415^13 mod 2537 = 2182. Con p = 43, q = 59 (φ = 2436) y e = 13, d = 937 (porque 13·937 ≡ 1 mod 2436). Descifrando 0981 0461: 981^937 mod 2537 = 0704 → 07 04 → HE, 461^937 mod 2537 = 1115 → 11 15 → LP; mensaje: HELP. En implementaciones reales el descifrado se acelera con el teorema chino del resto (CRT) computando la congruencia por separado en p y en q.

El módulo n

n = p·q define el tamaño del espacio de mensajes (m < n), es la base de todas las operaciones modulares, y su factorización es el problema difícil que sostiene la seguridad: si un atacante factoriza n, calcula φ(n) y deriva d. Lo público es n; lo secreto es su descomposición en p y q.