Fecha: 27 Agosto 2000
Hace pocos días (24 Agosto de 2000), una desagradable sorpresa se filtró por los canales de "los que entienden" en criptografía: un alemán llamado Ralf Senderek afirma haber descubierto un fallo en la estructura de claves del programa PGP. En el colmo de la arrogancia, pretende hacernos creer que nuestro programa favorito de cifrado tiene, no un pequeño bug de programación, sino un fallo de los gordos. Pretende incluso haberlo demostrado con ejemplos y archivos de claves. Pero lo peor es lo siguiente: !que tiene razón!
Cuando nuestro nunca bien ponderado José Manuel Gómez, de Kriptópolis, dio la alerta en su Boletín 191 da la alarma, la noticia no tenía más de 24 horas. En condiciones normales, no estaría escribiendo estas líneas, sino que me hubiese esperado a que el polvo se asentase. Pero la gravedad del asunto, unido a la rapidez con que se están desarrollando los acontecimientos, me han impulsado a redactar este Informe urgente. Probablemente tenga que actualizarlo en los próximos días, así que al loro.
Por de pronto, vamos a recapitular los principales actos de este pequeño drama. Soy un aguafiestas, así que os adelanto el final: el torpedazo no es cosa de broma, pero no ha hundido al barco. Como dijo cierto personaje de una película de Billy Wilder: la situación es desesperada, pero no grave.
¿Cuál es el problema?
El fallo descubierto por Senderek está relacionado con la opción de Clave de Descifrado Adicional, o ADK. Este es un mecanismo por el cual los mensajes son cifrados con dos claves públicas: la del destinatario, y una segunda perteneciente a la empresa o entidad bajo la que opera el usuario. Es una herramienta enfocada a un uso empresarial, y destinada a evitar el síndrome ahora-qué-hacemos. Es decir, permite a la empresa acceder a los mensajes de un empleado cuando éste no está disponible por cualquier motivo (despido, muerte, enfermedad, vacaciones con Curro, etc). No me extenderé en el tema aquí. Los lectores interesados pueden leer mis explicaciones en el Informe 6 y el
Curso de PGP (capítulo 4) sobre esta opción en PGP, así como los Informes 16, 17 y 18 sobre el tema del depósito de claves (key escrow) en general.
Comencemos por el principio. Cuando PGP saltó al entorno Windows 95 y similares, introdujo diversas opciones nuevas: la opción ADK anteriormente dicha, las nuevas claves Diffie-Hellman (con sus sub-claves de cifrado y firmado), nuevos algoritmos de cifrado simétrico, nuevo estándar para firma digital, etc. Esto obligaba a cambiar el formato de los archivos de claves. En el artículo de Senderek se pueden leer todos los detalles, aunque aquí no nos preocuparemos en tecnicismos. El hecho es que el formato de claves, conocido como Versión 3 (no confundir con la versión del programa en sí) fue cambiado por el de Versión 4.
En el nuevo formato de claves (versión 4), la información sobre los diversos elementos de una clave se almacena en forma de "paquetes": uno para la clave de cifrado, uno para la de firma, uno para cada firma que se ha realizado sobre nuestra clave, etc. La parte de la clave de cifrado varía poco entre las versiones 3 y 4. Como contraste, el paquete referente a la clave de firma varía sustancialmente. Cada paquete referido a una firma digital se compone a su vez de distintos subpaquetes, los cuales incluyen información adicional. Todos los subpaquetes se agrupan en dos "campos." Por si os habéis perdido, lo importante es esto: toda la información sobre firma que aparece en una clave está agrupada en dos campos de información.
Dicho esto, recordemos lo que significa una firma digital. Todo usuario de PGP sabe de la importancia de firmar digitalmente, ya que eso permite detectar cualquier alteración en el documento firmado. Puesto que la propia clave podría ser alterada por un atacante malicioso (basta con un editor hexadecimal), es de importancia crucial firmar la propia clave. A esta firma que la clave ha efectuado sobre sí misma la denominaremos "auto-firma" [self-signature]; de ese modo, la distinguimos de las firmas que otros pueden hacer sobre nuestra clave con el fin de atestiguar que esa clave es realmente nuestra.
No os preocupéis si no recordáis haberla firmado: las nuevas versiones de PGP lo hacen de forma automática por defecto. Podéis comprobarlo pinchando sobre vuestra propia clave; veréis un icono en forma de lápiz con el mismo nombre de vuestro clave, y viene indicado como "DSS ( o RSA) signature". En teoría, cualquier alteración no autorizada de nuestra clave daría una firma con la indicación "DSS (o RSA) corrupt signature."
Al firmar, lo que se hace es un proceso de dos partes. En la primera, el documento a firmar es resumido mediante la llamada función resumen o destilado [hash], que nos da un "condensado" del mensaje, esto es, una ristra de bits de menor longitud del mensaje pero que depende de éste. En segundo lugar, se encripta dicho resumen con la clave privada del firmante (sí, en este caso se puede cifrar con la clave privada). Puesto que el resumen depende de todo el mensaje, cualquier alteración del mensaje cambiaría el resumen, y por tanto el resultado de la firma sería diferente. Se sigue como colorario que el resumen ha de depender de todo el mensaje. En efecto: si hubiese una parte del mensaje que no formase parte del resumen, dicha parte podría ser alterada sin que variase el resumen ni, por tanto, la firma.
Bien, pues esta perogrullada es la madre de todos nuestros problemas. ¿Os acordáis de los dos campos en que se agrupa toda la información sobre firma dentro de una clave? Pues, por razones que todavía desconozco, uno de estos campos participa en el resumen [hash], y por tanto en la firma digital de la propia clave. Pero el segundo campo NO es resumido, y por tanto NO interviene en el proceso que genera la firma sobre una clave. Es decir: hay paquetes de información que se pueden alterar dentro de una clave PGP de tal forma que la alteración no puede ser detectada por la firma digital.
Supongo que quedará claro ahora por qué el fallo es tan importante. Si podemos alterar claves públicas a nuestro antojo (fecha de creación, caducidad, nombre de clave, ID de clave...), las consecuencias serán desastrosas. La firma sobre la clave no nos aseguraría que tenemos una clave legítima. Podría ser "trucada" por terceros para que cifrásemos los mensajes con una segunda clave sin nuestro conocimiento, o podrían darnos el cambiazo. Negro panorama, donde los haya.
Pero sólo podrán alterarse impunemente aquellos fragmentos de información que hayan sido almacenados en la porción no resumida de la clave. Y ahí es donde entra el análisis de Senderek.
Disección
Nuestro alemán recurrió a un proceso empírico. Es decir, construyó un conjunto de claves y las fue trucando punto por punto, comprobando después cuáles son los efectos. Probó con las versiones 2.6.3ia y 5.0i (Unix), 5.5.3i y 6.5.1i (Windows), y GnuPG 1.0.1 (Unix). Mostraré aquí los resultados para la versión 6.5.1i de Windows. Lo que sigue puede pareceros algo confuso, pero os animo a que intentéis seguir el proceso de disección. Si os atragantáis, saltaos esta sección y nos veremos más abajo.
Adelante los valientes, En primer lugar, se probó una clave DH/DSS (Diffie-Hellman) que ya tenía una clave de descifrado adicional (ADK). Los intentos para alterar la fecha de creación y dicha ADK resultaron infructuosos: la firma de la clave da el aviso de "firma corrupta" (corrupt signature). Es decir, dichos datos se guardan en la porción "resumida" [hashed] de la clave.
Pero si no se puede alterar la ADK existente, podemos probar a insertar una segunda ADK en la porción no resumida [non-hashed] de la auto-firma. Y en efecto, funciona: ahora aparecen dos ADKs, la original (ubicada en la parte resumida) y la "trucada" (introducida en la parte no resumida). Es decir, los mensajes serán cifrados con tres claves: la del destinatario, la ADK original y la ADK trucada.
Cambiando el tipo de subpaquete se puede transformar la nueva ADK en un revocador "trucado." Senderek afirma tan sólo que en ese caso la clave funciona como la original (antes de las alteraciones); con mi versión 6.5.3 he comprobado que, en efecto, aparece un revocador trucado. Esto significa que otra persona puede revocar nuestra clave y diseminar dicha revocación, lo que nos hará la pascua, ya que dicha revocación está diciendo "soy una clave que no debe ser usada más." Esto equivale a una alteración que podríamos llamar "perro del hortelano": no descifra nuestros mensajes, pero tampoco dejará cifrar a los demás.
Como segunda prueba, veamos qué pasa cuando se intenta trucar una clave DH/DSS que no tiene una ADK. Si introducimos un subpaquete de ADK en la parte no-resumida de la auto-firma, PGP muerde el anzuelo: el nuevo subpaquete aparece como una ADK legítima: el creador de dicha ADK (el trucador) podrán por tanto leer los mensajes cifrados por el remitente.
Por otro lado, podemos añadir (legítimamente) una firma digital proveniente de una autoridad de certificación AC (sea ésta una empresa o el amigo de la esquina que da fé de que mi clave realmente me pertenece); llamemos a dicha firma "certificado" para distinguirla de la auto-firma. A continuación intentamos añadir el subpaquete de ADK en la parte no-resumida del certificado. En este caso, no sucede nada. Es decir, si queremos dársela con queso al programa, hemos de alterar la parte no-resumida correspondiente a la auto-firma; trastear las otras firmas digitales contenidas en la clave no sirve para nada.
Tercera prueba: partimos de una clave RSA sin ADK. A ver si las venerables claves de antaño, resisten mejor. Siguiendo un proceso similar, intentamos meter una clave ADK trucada de tipo DH/DSS. Resultado: positivo. ¿Y si intentamos colar una clave ADK de tipo RSA? Resultado: positivo.
No obstante, hay que tener en cuenta que ello solamente fue posible cuando las claves RSA están en el formato versión 4. Normalmente, dichas claves se encuentran guardadas como versión 3, incluso en las últimas versiones de PGP. De hecho, Senderek tuvo que sudar un poco para convertir las claves RSA (normalmente en versión 3) a la versión 4. El proceso de cambio de versión (de la 3 a la 4) no es fácil, y puede detectarse (el ID de clave y la huella cambian, y la auto-firma aparece con un mensaje de firma desconocida "unknown signature"). Pero el caso es que puede hacerse.
El resultado de todo este barullo es el siguiente: se puede insertar una ADK en una clave que carezca de ésta, o bien añadir una segunda ADK cuando ya se tiene una. Dicha alteración puede hacerse de forma que no sea detectable (es decir, que no aparezca el mensaje "corrupt signature" en la auto-firma).
¿Y qué sucede con las otras versiones? La 5.5.3i para Windows se comporta de forma parecida. La diferencia más notable es que, en apariencia, no se pueden "trucar" las claves RSA. Sin embargo, una clave RSA convertida a la versión 4 aparece ante nuestros ojos como si fuese de versión 3. Es decir, no tenemos asegurado que las claves RSA sean inmunes al trucaje bajo PGP 5.5.3i.
La versión 5.0i para Unix tiene algún problema para importar las claves trucadas. Pero, si no he entendido mal, esta versión no traga los trucajes: son detectados gracias a la auto-firma y los mensajes se cifran con la clave correspondiente, NO con las ADKs. Las otras dos versiones comprobadas tampoco admiten estas manipulaciones. Los motivos son diferentes. La versión 2.6.3ia para Unix (y, en general, las de tipo 2.6.x para cualquier sistema operativo) era anterior a la aparición de las claves DH/DSS y se mantenían dentro de la versión 3 de formato de claves; simplemente "no traga" nada que tenga que ver con la versión 4.
En cuanto a la GnuPG 1.0.1 para Unix, no parece que la adición de la ADK nueva pueda llevarse a cabo sin ser detectada. Aquí hay todavía discrepancia de opiniones. José Manuel Gómez afirma que aunque GnuPG no cifra con ADKs, las claves DH/DSS creadas con esta versión son tan vulnerables como las demás. Aunque el análisis de Senderek no afirma eso explícitamente, al final saca la misma conclusión: son peligrosas. Hay que añadir que el análisis de los "trucajes" se realizó con GnuPG, que permite una cómoda y completa visualización de los contenidos de cada clave.
La conclusión que podemos extraer de su trabajo es la siguiente:
La única forma de evitar el ataque de las "ADKs trucadas" es usar una versión que NO use para nada la versión 4 de formato de claves. Esto excluye para su uso no solamente las claves Diffie-Hellman/DSS, sino las claves RSA que puedan transformarse en claves con versión 4 de formato de claves. Las claves DH/DSS están especialmente afectadas, pero incluso las claves RSA pueden ser susceptibles de modificación en algunas versiones de PGP.
Como sugerencia final, Ralf Senderek recomienda usar PGP 2.6.3, la única versión -según él- que evita los problemas asociados a la versión 4 de formato de claves (ya que no las usa). Hay que tomar en consideración que, aunque no se han comprobado todas las versiones de PGP (en particular, las de Mac destacan por su ausencia), no hay motivo para creer que no sean igualmente vulnerables. Parece ser que el trucaje de Senderek funciona siempre que la versión 4 de formato de claves sea posible. No hay versión 4, no hay trucaje.
A la vista de este estudio, ¿qué hacemos? Daré mis recomendaciones en breve. Pero antes, considero de importancia destacar el seguimiento del fallo, "hora a hora." ¿Cómo se dio la alarma, y cómo se está reaccionando ante ella?
Salta la alarma
El autor del estudio, según sus propias palabras, presentó su estudio al público el día 22 de Agosto, e informó inmediatamente a "personas que trabajan en seguridad informática". No indica cuáles son dichos expertos, pero el CERT (Equipo de Respuestas sobre Emergencias Informáticas), encargado de diseminar los fallos de programación de programas, alertas de virus, etc, dio un aviso (CA-2000-18) el día 24 con el título "PGP puede cifrar datos con ADKs no autorizadas," aunque conteniendo algunas incorrecciones que fueron corregidas por el propio Senderek (ver tales correcciones en http://cryptome.org/pgp-badbug.htm).
Ese mismo día, Network Associates (NAI, propietaria de PGP) recibió dicho anuncio y lo diseminó, en menos de 24 horas, en una página especial: http://www.pgp.com/other/advisories/adk.asp. En dicha página, desde entonces, se añaden las últimas novedades a este problema.
Mientras los chicos de NAI se ponían manos a la obra, la noticia saltaba de un nodo a otro de la Red. El día 25, Cryptome da su primer aviso del problema (http://cryptome.org/pgp-badbug.htm). Y ese mismo día, al filo de la medianoche, el "alcalde" de Kriptópolis da la alarma en su boletín 191, prodigio de claridad y complitud considerando la poca información disponible en ese momento.
[Inciso: esta crisis me ha demostrado que José Manuel Gómez no tiene existencia real, o si no ¿cómo le ha dado tiempo a dar un aviso y un análisis en menos de un día, eh? Hasta ahora creía que simplemente lo habían clonado. Ahora sospecho que ni siquiera tiene existencia física: es un programa de ordenador diseminado por toda la Red, husmeando en busca de información. ¿Será José Manuel Gómez el código clave para un Echelon a la española? Seguiremos informando ...;-)) ]
Las primeras noticias desde NAI (al menos, las primeras que yo recibí) provienen de Will Price, quien ya el día 24 recordó que PGP da un aviso cuando se cifra con una clave que tiene una ADK (PGPkeys \ Edit \ Options \ Advanced \ "Warn when encrypting to keys with an ADK"). Eso es cierto, aunque malamente arregla el problema. El propio "tío Phil" (Zimmermann) emite un comunicado en el que afirma que están trabajando en ello y que esperan tener una versión corregida para el viernes 25, que "filtrará los paquetes ADK inapropiados."
Moviéndose rápido
Incluso considerando que NAI literalmente se la estaba jugando en este asunto, la rapidez con que los chicos de PGP reaccionaron resulta algo insólito. En un esfuerzo relámpago, el sábado 26 (es decir, dos días después de ser notificados del problema) !ya tenían lista una versión corregida! Cuando menos, esto dice mucho en favor de los fabricantes y debería tomarse como ejemplo para otros fabricantes de software. !Que cunda el ejemplo, y no el pánico!
Lo curioso es que esta nueva versión, llamada 6.5.8, apareció en lugares como Cryptome y la Página Internacional de PGP antes de que apareciese en el propio servidor norteamericano de pgp.com (se incluyó el domingo 27, para las versiones gratuitas, en la página de distribución del MIT). Tambíen se prometen una especie de "paño caliente" (HotFix) para las versiones 6.5.2a y 6.5.3. Y viene todo en sabores de Windows y Macintosh, lo que implica que las versiones de Mac también se cree están afectadas.
Tal es la rapidez con la que se desarrollan los acontecimientos, que se están preparando más parches en la anteriormente página PGP ADK Security Advisory, cuya visita recomiendo vivamente. Tienen para rato, porque este fallo afecta no solamente al programa PGP, sino a los demás primos de su familia, entre ellos: PGP Certificate Server, PGP Certificate Server Freeware, PGP Command Line, PGP Command Line Freeware, PGP e-Business Server ... y no debemos de olvidarnos de PGPsdk, el paquete de desarrollo de software (Software Development Kit) con el que se desarrollan programas compatibles con PGP como los plug-ins para programas de correo electrónico, las versiones de PGP para Linux, etc. Todo un curro. Y veremos si funciona.
Soluciones quiero
Aparte de los parches que se están publicando (y que recomiendo al toque de ya), NAI ha procedido a un chequeo de su servidor de claves (certserver.pgp.com) para comprobar si hay alguna clave "trucada" en su base de 1.2 millones de claves. Aparentemente, ninguna lo ha sido. Asimismo, afirman haber instalado una actualización en el software de los servidores certserver.pgp.com y pgpkeys.mit.edu para "limpiar" las nuevas claves que se envían a dichos servidores, eliminando las firmas que hayan sido manipuladas . Han preparado una pequeña utilidad, PGPrepair 1.0, para examinar los archivos de claves y reparar claves manipuladas. En suma, una labor ingente, sobre todo teniendo en cuenta el escaso tiempo de que han disponido.
Sin embargo, en mi opinión todo esto es aconsejable pero no suficiente. Sencillamente, no creo que el problema sea tan fácil de solucionar. La pifia yace en el núcleo de las claves, ya que afecta a su formato. Construir parches que eliminen las ADKs en las partes no resumidas [non-hashed] de la clave, suponiendo que funcione sin problemas (y que no haya modo de engañar al parche) es eso, un parche, pero es como si arreglásemos el casco endeble de un buque poniendo una bomba de agua: sacará el agua del barco en caso de que se abra una brecha, pero no fortalece el casco.
Imagino que queréis recomendaciones por mi parte. Pues para eso estamos, faltaría más. Mis sugerencias, en estos momentos, son las siguientes:
Instalar los parches que están preparándose, o (en el caso de un nuevo usuario) instalar directamente la versión "parcheada" 6.5.8
Usar el comprobador PGPrepair, para asegurarse de que nuestro archivo de claves está en buen estado.
Comprobar si tenemos en nuestro archivo de claves alguna con una ADK asociada. Eso es fácil de comprobar. Basta abrir PGPkeys y activar la opción View/ADK. Aparecerá una columna "ADK" con una bola de color. Si es gris, no hay ADK. Pero si es roja, significa que esa clave tiene una ADK asociada. !Que nadie chille! Puede corresponder a una ADK legítima. Si tiene razones para pensar que el dueño de dicha clave trabaja en una organización o empresa, es posible que se trate de la ADK de ésta. Si desea enviar un mensaje a dicha persona, compruebe antes con ella si tiene una ADK válida o no. Siempre es bueno saber cuando ciframos a una clave que tiene una ADK, legítima o no.
No recomiendo fiarse simplemente del aviso que da PGP (el de "Warn when encrypting to keys with an ADK"). Yo mismo, usando esa opción y las claves de prueba de Senderek, he cifrado un mensaje con una clave que contenía dos ADK (una de ellas, trucada) !y no me ha salido ningún aviso! Afortunadamente, hay otra indicación. Al dar la orden de cifrar, aparece la ventana Encrypt Message To ... (Cifrar Mensaje A...), y en la sección Recipients (Destinatarios) aparecen tanto la clave del destinatario como la(s) ADK(s). Si intentamos quitar alguna ADK, sale un aviso de que efectivamente es una ADK y que su eliminación podría "violar la política establecida para otras claves." Para políticas estamos.
Tampoco recomiendo poner las carretas en círculo y volver en masa a las venerables versiones pre-Windows. De momento, creo que no hay motivos para ello, y que la situación puede arreglarse a corto y medio plazo. Simplemente, estemos al loro y comprobemos que nuestro archivo de claves no tiene ninguna clave con "corrupt signature"; y si tiene una clave con ADK, mil ojos al usarla.
© Arturo Quirantes
2005. Correo electrónico: aquiran arroba
ugr.es
Vuelta a la sección Informes del Taller de Criptografía