Encriptación de contraseñas

dibu
10 de Agosto del 2009
Por favor, ¿alguien tiene alguna función o algùn ejemplo que permita encriptar y desencriptar contraseñas?

David
10 de Agosto del 2009
Hola

Depende de lo que quieras hacer. Con el caso de las contraseñas lo habitual no es encriptarlas, sino generar códigos hash de las mismas, que es lo que se guarda. Cuando se quiere validar una contraseña, se obtiene el hash de la proporcionada por el usuario y se compara dicho código con el almacenado en la base de datos de usuarios.

Ahora bien, la pregunta es qué función hash emplear. Lo más recomendable es emplear MD5 o (mejor aún) SHA1.

MD5 es un algoritmo de generación de resúmenes de mensajes de longitud arbitraria que genera salidas (resúmenes o firmas) de 128 bits.

SHA1 es otro algoritmo de generación de resúmenes de mensajes de longitud inferior a 2^64 bits que genera salidas de 160 bits.

Ambos algoritmos se caracterizan por lo siguiente:

- es virtualmente imposible que dos mensajes distintos produzcan la misma firma.

- conocida la firma de un mensaje, es computacionalmente imposible obtener el mensaje.

- no se basan en clave, sino en una funoión criptográfica perfectamente conocida, pero de una sola vía (el conocimiento de la entrada determina el conocimiento de la salida, pero no a la inversa).

Así que esto es lo único que necesitamos.

Para almacenar las contraseñas utilizaremos normalmente un campo de texto. Si lo que guardaremos es el código SHA1, necesitaremos asegurar que nos quepa toda la firma de la contraseña en el campo. Otro detalle a tener en cuenta es que no es conveniente almacenar bytes de datos (no caracteres, la salida de MD5 y de SHA1 son bytes arbitrarios) en un campo de tipo VARCHAR. Podríamos emplear otro tipo de campo (un BLOB), pero es más fácil:

1. Guardar en el campo no los bytes generados directamente, sino su traducción a dígitos hexadecimales: si queremos guardar los bytes 0x13, 0xF2, ... guardaremos la cadena '13F2...'. De este modo, el campo de la contraseña debería poder almacenar al menos 40 caracteres para SHA1 o 32 para MD5.

2. Guardar en el campo la conversión del resumen generado a BASE64. BASE64 es un sistema de traducción de datos binarios arbitrarios a código ASCII (es lo que se usa, por ejemplo, para el envío de adjuntos a través de correo electrónico). Con este sistema, ahorraremos espacio de almacenamiento: para SHA1 no necesitaremos más de 28 caracteres.

Por ejemplo, Visual Studio .NET emplea la primera opción para encriptar las contraseñas. Yo empleo siempre la segunda opción. Utiliza esta clase:

import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import sun.misc.BASE64Encoder;
import sun.misc.CharacterEncoder;

public final class SHA1BASE64 {
public static String encriptar(String textoplano) throws IllegalStateException {
MessageDigest md = null;

try {
md = MessageDigest.getInstance("SHA"); // Instancia de generador SHA-1
}
catch(NoSuchAlgorithmException e) {
throw new IllegalStateException(e.getMessage());
}

try {
md.update(textoplano.getBytes("UTF-8")); // Generación de resumen de mensaje
}
catch(UnsupportedEncodingException e) {
throw new IllegalStateException(e.getMessage());
}

byte raw[] = md.digest(); // Obtención del resumen de mensaje
String hash = (new BASE64Encoder()).encode(raw); // Traducción a BASE64
return hash;
}
}

Cada vez que quieras guardar una contraseña, lo que guardarás será la salida del método:

SHA1BASE64.encriptar(contraseña);

Cuando quieras verificar una contraseña, no comprabarás la igualdad de la misma con lo que tengas en la base de datos directamente, sino la salida del mismo método.

Perdona por el rollo, pero es básico saber lo que se hace para poder hacerlo bien...


Salud

David

estudiante1 howard
22 de Septiembre del 2010
muy buena tu explicacion.
mi pregunta es:
¿existe algun metodo para desencriptar?
o cual seria la mejor forma para mostrar una contraseña??
gracias

mqt
10 de Agosto del 2009
muy buena la explicacion , muchas gracias