martes, 23 de febrero de 2010

OpenSSH, hash / digest [II]

Explicación
Hoy vamos a explicar lo que es un hash o un "digest" de un mensaje. Cuando nosotros tenemos unos datos determinados, ya sean ficheros de texto o binarios, podemos hacer un resumen de estos datos. Que significa hacer un resumen? Pues muy fácil. Tenemos una fotografía, y queremos sacar su "hash" ( también llamado resumen o digest, ok? ). Pues lo que hará el programa encargado de hacer el hash es lo siguiente:
  • Va a comprimir la foto lo más que pueda
  • Va a partir la foto en trozos de un tamaño determinado
  • Aplicará una función a cada uno de los trocitos.
  • Esta función siempre devuelve un nº de bits determinados.
  • El resultado se combina siempre con el resultado anterior.
Lo que nos promete el algorítmo es que si cambia un solo bit del fichero original, la función de hash va a ser completamente diferente que el resultado de la función del fichero original. De este modo podemos saber si un fichero se ha modificado. Esto se puede hacer con todo tipo de archivos.
Y una propiedad que puede ser obvia pero que debe comentarse, es que de un "hash" no se puede volver a la información original. Es una operación de un solo sentido. Podemos hacer el hash de "hola". Pero del hash resultante no lo podemos volver a su estado original (en nuestro caso a la palabra "hola" ). Es imposible.

Para que se usa algo así?
Bueno, en seguridad tiene mucha utilidades, pero un ejemplo muy fácil de entender es el siguiente: Imagina que quieres mandarle una pelicula a tu amigo. Para saber si le ha llegado bien, lo que se hará será lo siguiente: calcular el hash en mi PC y que el amigo calcule su función de hash en su PC. Si son iguales, sabemos que el fichero se ha mandado bien.
También sirve para guardar passwords de modo seguro, etc...

Tipos de algorítmos de hash?
Bueno, pues ya los listé en el post anterior. Los algorítmos soportados por OpenSSL son los siguientes:
md2, md5, mdc2, rmd160, sha, sha1, sha224, sha256, sha384, sha512

Es posible que dos resumenes de dos ficheros diferentes nos den el mismo resultado?
Teoricamente si. Pero la la probabilidad de que esto ocurra es MUY baja. Tal que así:
  • Si utilizamos un algorítmo como md5 que hace un resumen de 128 bits existe la probabilidad de 1/(2^128) que es lo mismo que 1 / 340282366920938463463374607431768211456
  • Si utilizamos sha256 la probabilidad de 1 / (2^256)
Recordemos que 256 bits no es el doble de posibilidades que 128 bits! El doble de 128 bits es 129 bits!!


Vale, la teoría está explicada. Pero mejor acabarlo de pulir con un par de ejemplos:

Creamos un fichero de texto con el siguiente comando:
$ echo "TEXTO TEXTO TEXTO" > ar1.txt
Y ahora procedemos a calcular su función de hash:
$ openssl dgst -md5 ar1.txt
MD5(ar1.txt)= c89977bcf69702e21a82575b187459d4

Bien, que significa el resultado? Pues bien, que aplicando el hash MD5 del fichero "ar1.txt" tenemos un resultado tal y como se ve aquí arriba.

Vale, vamos a hacer un cambio tonto en el fichero:
$ echo "TEXTO TEXTo TEXTO" > ar2.txt
Y ahora procedemos a calcular su función de hash:
$ openssl dgst -md5 ar1.txt ar2.txt
MD5(ar1.txt)= c89977bcf69702e21a82575b187459d4
MD5(ar2.txt)= 31b68c308e9299482ef2b2754df853be

Ahora, como podeis ver he hecho el hash de los dos ficheros "ar1.txt" y "ar2.txt". Como se puede apreciar claramente, los hashes son completamente distintos uno del otro, lo que significa que los ficheros no son esctrictamente iguales. Es de vital importancia entender que un cambio, por insignificante que sea, nos devuelve un hash completamente diferente del original.

Si queremos utilizar programas más simples de usar que openssl podemos utilizar:
  • md5sum
  • sha1sum
  • sha256sum
La sintaxis es mas sencilla. Aqui un ejemplo aplicable a todos los algorítmos:
$ md5sum ar1.txt
c89977bcf69702e21a82575b187459d4 ar1.txt
Y el resultado, como podeis apreciar, es muy similar ( y el hash idéntico, evidentemente ).

Espero que lo hayan entendido.

Saludos!

4 comentarios: