Firmas Digitales

waxseal.jpg

Imagínese la siguiente situación: usted recibe una carta del gobierno ruso en donde se le informa que un familiar muy lejano ha muerto y nadie ha reclamado sus restos; le informan que ellos saben que usted es su familiar más cercano, por lo que si usted quisiera podría mandar el dinero necesario para darle un entierro digno.

El problema principal es: como no tiene manera de contactar al familiar no puede saber si se trata de una estafa. Así que debe corroborar de alguna manera que en verdad la oficina del gobierno ruso mandó ese documento, pero también imagínese que para corroborar eso tiene que pasar por niveles de burocracia insufribles, además debe hablar por teléfono en ruso y de larga distancia. Una situación difícil.

Lo que en el pasado se hacía cuando se mandaba información importante entre reyes y nobles era poner un sello de cera sobre la carta. Se vertía cera recién fundida sobre el doblez de cierre en la carta, y con un sello único de metal, que pertenecía a la persona, se presionaba sobre la cera. Esto permitía corroborar la autenticidad del documento, y que su contenido no había sido alterado en el camino.

Nota: Aquí se va a usar RSA, pero bien se puede usar cualquier otro algoritmo de cifrado asimétrico (o de llave pública).

Cómo resolver el problema

Lo que se va a resolver esta vez es que el documento sea auténtico, y que no ha sido modificado. Para ello vamos a hacer uso de nuestro conocido algoritmo RSA.

Voy a suponer que ya se conoce todo lo necesario para usar RSA. Sólo haremos un recuento rápido:

  1. Se necesita un alfabeto numerado.
  2. Se necesita construir la llave pública [n,e]
  3. Se calcula la llave privada d (que es un entero positivo)

Una primera aproximación

Si deseamos mandar un mensaje, primero tenemos que mapearlo con el alfabeto numerado, para así tener una cifra entera M. Esto es natural en una computadora pues todos los caracteres tienen un número binario asociado; y, a partir de ahora vamos a considerar que el mensaje M es a la vez una cifra y un texto legible. Esperando que lo anterior no sea muy complicado para cualquiera familiarizado con temas de computación.

Para firmar un mensaje se tiene que verificar que (M,n)=1. Luego se calcula M_f=M^d, y se manda el mensaje M junto con M_f y la clave pública.

Recordando lo que se usó para descifrar mensajes en RSA, tenemos que: M^{ed} \equiv M \pmod {n}. Por lo que si alguien quiere verificar que es auténtico nuestro mensaje sólo tiene que verificar que M_f^{e} \equiv M \pmod {n}, o lo que es lo mismo: que el residuo que queda al dividir M_f^{e} - M entre n, es cero.

Hay que observar que si alguien quisiera alterar el mensaje M, tendría que conocer el valor de d para poder calcular de nuevo M_f, pues si no el receptor se daría cuenta de que han alterado el documento o que no lo envió la persona esperada.

La solución real

Como podrán haber intuido, la solución anterior es impráctica, pues calcular M_f es brutal. Por lo que ahora lo que se hace uso de una función de resumen (o función hash).

Una función hash es una manipulación matemática que: pretende asociarle a una cadena de bits, uno y sólo un valor (llamado hash). Además pretende cumplir con la propiedad de que si dos hashes son iguales, entonces debe tratarse de la misma cadena de bits. O sea, es una función biyectiva. Pero dada la naturaleza de esta pretensión, y sabiendo que las funciones hash más usadas tienen una cantidad limitada de posibles valores para devolver, siempre existen al menos dos cadenas de bits con el mismo hash. Para fines prácticos lo que se hace es: idear la función hash de tal manera que sea muy difícil construir deliberadamente dos combinaciones que tengan el mismo hash, y que sea muy difícil que se pueda reconstruir la cadena a partir de su hash.

Considerando lo anterior: actualmente para firmar un mensaje se hace uso de una función hash (como SHA1 o MD5) para obtener el hash (h) de nuestro mensaje M. Luego tenemos que hacer el mismo procedimiento que se hacía para mandar mensajes cifrados con RSA, pero en este caso sólo se va a cifrar h. Recordemos que se tiene que dividir por bloques, pero en este caso no se eleva a la e sino que se eleva a la d; y, de la misma manera que en RSA después se calculan los residuos. Se manda finalmente h cifrado y la llave privada.

El receptor del mensaje tiene que descifrar completamente el hash cifrado que le llegó, usando la llave pública; y, éste tiene que coincidir con el hash del mensaje original, lo que verificaría que el mensaje no fue alterado y fue enviado por la persona que se supone que lo envió.

Observación importante

Verificar la firma de un documento se basa en que suponemos que sólo el emisor conoce d; además es muy difícil calcular d a partir del hash cifrado. También suponemos que cuando Juan Pérez nos envió por primera vez su llave pública, en verdad esa era de Juan Pérez y de nadie más.

El problema ahora es: ¿cómo sabemos que el que mandó el mensaje firmado es efectivamente Juan Pérez si nunca antes habíamos recibido nada de él (por lo que no conocemos su llave pública)? Suponiendo que no podemos preguntar personalmente a Juan Pérez sobre su llave pública.

En un próximo artículo se abordará el problema anterior.

Un commentario
Deja un comentario