He estado luchando con GPG últimamente y (¡por fin!) lo he conseguido funcionar. Ahora puedo ingresar un blob cifrado en gpg.exe y generará la versión en texto sin formato, asumiendo que, por supuesto, es un blob de cifrado válido, lo que significa que su clave de descifrado está en mi lista de claves privadas/"identificaciones criptográficas".
Mi pregunta es: ¿cómo determina GPG exactamente cuál de estas claves probar? ¿Esa información está incorporada de alguna manera en el blob de cifrado? ¿O simplemente los prueba a ciegas, uno por uno, hasta que uno lo descifra con éxito?
Sería bueno finalmente obtener respuesta a esta pregunta porque me lo he estado preguntando durante años. Se siente tan "crudo" y "baja tecnología" que simplemente los analice todos de esa manera. Especialmente si, por ejemplo, empiezo a alojar algún tipo de servicio en el que tienen que pasar miles de claves privadas de personas para ver si un nuevo mensaje entrante coincide con alguna de ellas. Simplemente no parece "escalar".
¡Espero que haya algo en el texto cifrado que le indique a GPG qué clave probar! ¿Es ese el caso?
Respuesta1
El paquete OpenPGP resultante contiene de hecho elID de subclave de cifradodel destinatario que se supone que puede descifrarlo. Por ejemplo:
$ date | gpg --encrypt | pgpdump
Old: Public-Key Encrypted Session Key Packet(tag 1)(524 bytes)
New version(3)
Key ID - 0xCE7B0F19551034EF
Pub alg - RSA Encrypt or Sign(pub 1)
...
New: Symmetrically Encrypted and MDC Packet(tag 18)(83 bytes)
...
Si hay varios destinatarios, habrá varios paquetes de "Clave de sesión", uno para cada destinatario, y todos ellos contendrán versiones cifradas diferentes de la misma clave simétrica.
(Creo que la próxima versión de la especificación, v5, planea tener huellas digitales de subclave completas. Sin embargo, en esta situación, las ID de clave truncadas son suficientemente buenas).
Dicho esto, GnuPG tiene una opción llamada --throw-keyids
, que hace que todos los paquetes de claves de sesión tengan el mismo ID de clave 0x0000000000000000. Cuando eso sucede, el destinatario intenta descifrar el paquete por fuerza bruta, utilizando todas las subclaves secretas con capacidad de cifrado que tenga.
También hay una --hidden-recipient
opción que permite ocultar destinatarios individuales de la misma manera, de modo que pueda tener una combinación de ID de clave nulas y no nulas en el mensaje resultante. Esto podría resultar útil para implementar Bcc:
copias carbón en clientes de correo electrónico.
Ambas opciones se pueden utilizar cuando necesita intercambiar mensajes a través de algo como un tablero de anuncios público/buzón/subreddit y no desea revelar el destinatario previsto.
$ date | gpg -e --recipient Alice --hidden-recipient Robert | gpg --list-packets
gpg: anonymous recipient; trying secret key CE7B0F19551034EF ...
gpg: anonymous recipient; trying secret key DCDBB36BD91759A3 ...
gpg: okay, we are the anonymous recipient.
gpg: encrypted with 4096-bit RSA key, ID CE7B0F19551034EF, created 2009-10-31
gpg: encrypted with RSA key, ID 0000000000000000
# off=0 ctb=85 tag=1 hlen=3 plen=524
:pubkey enc packet: version 3, algo 1, keyid 0000000000000000
data: [4095 bits]
# off=527 ctb=85 tag=1 hlen=3 plen=524
:pubkey enc packet: version 3, algo 1, keyid CE7B0F19551034EF
data: [4092 bits]
# off=1054 ctb=d2 tag=18 hlen=2 plen=80 new-ctb
:encrypted data packet:
...