Una función `hash' es una función múltiple que asigna su entrada a un valor dentro de un grupo finito. Por regla general este grupo es un rango de números naturales. Un modelo simple de función `hash' es f(x) = 0 para todo entero x. Una función hash más interesante es f(x) = x mod 37, que asigna x al resto de la división x entre 37.
Una firma digital en un documento es el resultado de aplicar una función `hash' al documento. Para que sea de utilidad, la función `hash' necesita satisfacer dos propiedades importantes. Primero, debería ser difícil encontrar dos documentos cuyo valor para una función `hash' sea el mismo. Segundo, dado un valor `hash' debería ser difícil de recuperar el documento que produjo es valor.
Algunos sistemas de cifrado de clave pública[1] se pueden usar para firmar documentos. El firmante cifra el documento con su clave privada. Cualquiera que quiera comprobar la firma y ver el documento, no tiene más que usar la clave pública del firmante para descifrarla. Este algoritmo satisface las dos propiedades necesarias para una buena función de `hash', pero en la práctica este algoritmo es demasiado lento para que sea de utilidad.
Como alternativa está el uso de funciones `hash' designadas para satisfacer estas dos importantes propiedades. SHA y MD5 son dos ejemplos de este tipo de algoritmos. Al usar uno de estos algoritmos, un documento se firma con una función `hash', y el valor del `hash' es la firma. Otra persona puede comprobar la firma aplicando también una función `hash' a su copia del documento y comparando el valor `hash' resultante con el del documento original. Si concuerdan, es casi seguro que los documentos son idénticos.
Claro que el problema está en usar una función `hash' para firmas digitales que no permita que un atacante interfiera en la comprobación de la firma. Si el documento y la firma se enviaran descifrados, un atacante podría modificar el documento y generar una firma correspondiente sin que lo supiera el destinatario. Si sólo se cifrara el documento, un atacante podría manipular la firma y hacer que la comprobación de ésta fallara. Una tercera opción es usar un sistema de clave pública híbrido para cifrar tanto la firma como el documento. El firmante usa su clave pública, y cualquiera puede usar su clave pública para comprobar la firma y el documento. Esto suena bien, pero en realidad no tiene sentido. Si este algoritmo hiciera el documento seguro también lo aseguraría de manipulaciones, y no habría necesidad de firmarlo. El problema más serio es que esto no protege de manipulaciones ni a la firma, ni al documento. Con este algoritmo, sólo la clave de sesión del sistema de cifrado simétrico, es cifrada usando la clave privada del firmante. Cualquiera puede usar la clave pública y recuperar la clave de sesión. Por lo tanto, es sencillo para un atacante recuperar la clave de sesión y usarla para cifrar documentos substitutos y firmas para enviarlas a terceros en nombre del remitente.
Un algoritmo que funciona es aquél que hace uso de un algoritmo de clave pública para cifrar sólo la firma. En particular, el valor `hash' se cifra mediante el uso de la clave privada del firmante, de modo que cualquiera pueda comprobar la firma usando la clave pública correspondiente. El documento firmado se puede enviar usando cualquier otro algoritmo de cifrado, o incluso ninguno si es un documento público. Si el documento se modifica, la comprobación de la firma fallará, pero esto es precisamente lo que la verificación se supone que debe descubrir. El "Digital Signature Standard" (DSA) es un algoritmo de firmado de clave pública que funciona como hemos descrito. DSA es el algoritmo principal de firmado que se usa en GnuPG.
[1] | El sistema de cifrado debe poseer la propiedad de que la clave pública o la privada puedan ser usadas por el algoritmo de cifrado como clave pública. RSA en un ejemplo de este tipo de algoritmo, mientras que ElGamal no. |