Criptografía: Algoritmos de Digestión de Mensajes

04/Feb/2013 Java , , 2 Comentarios

¡Buenas! Hoy les voy a traer algunos conceptos de encriptación y cómo Java los soporta.

Supongamos que tenemos una aplicación en la que almacenamos información confidencial y no queremos que sea mostrada como texto plano o en el código de la aplicación, entonces es aquí donde entra la criptografía.

Dentro de la criptografía existen varios algoritmos con diferentes características. Nosotros hoy veremos los Algoritmos de Digestión de Mensajes o de Hash acompañados de una pequeña implementación sobre su uso en Java.

Algoritmos de Digestión de Mensajes

Estos algoritmos son tales que, a partir de un mensaje y mediante ciertas operaciones matemáticas, generan otro mensaje denominado 'Huella Digital' (que según el algoritmo que usemos puede ser de tamaño fijo o no) que cumple con las siguientes características:

  1. Es incomprensible a simple vista.
  2. Cada huella es única para cada mensaje.
  3. Dos huellas son iguales si y solo si el mensaje original también lo es.
  4. Es unidireccional, es decir que no se puede reconstruir el mensaje original a partir de su huella digital.

Usaremos este método para probar los distintos algoritmos de digestión que soporta Java mediante la clase MessageDigest:

  1.  
  2. public static String digest(String str, String alg) {
  3. try {
  4. MessageDigest md = MessageDigest.getInstance(alg);
  5. // Indicamos el algoritmo a usar
  6.  
  7. return new String(md.digest(str.getBytes()));
  8. // 'Digerimos' el mensaje
  9. System.out.println("el algoritmo " + alg + " no existe");
  10. return null;
  11. }
  12. }
  13.  

Algoritmos y sus resultados:

 ·MD2:    digest("lineadecodigo", "MD2")     -> zA��&�#K��F%5
 ·MD5:    digest("lineadecodigo", "MD5")     -> �e����_m9E	�S�*
 ·SHA1:   digest("lineadecodigo", "SHA-1")   -> &�4!�7�Rr�6/�fs�
 ·SHA256: digest("lineadecodigo", "SHA-256") -> c�� �j 21��?։��*����,l���
 ·SHA384: digest("lineadecodigo", "SHA-384") -> pNƒ+���u��w�g;���� �:Yc�(
 ·SHA512: digest("lineadecodigo", "SHA-512") -> O� ֐���i�Q�>��G�8���o�C[:-�ga4:�n3hg�Ѻ�"�o~�Ǡ�#0�(�

Incomprensible, ¿verdad? ¡Esa es la idea! Pero... ¿cómo se usan?

La idea del siguiente ejemplo hace hincapié en las propiedades de las huellas digitales mencionadas anteriormente:

Supongamos que tenemos una aplicación en la que se requiere que los usuarios se identifiquen mediante Nombre de Usuario y Contraseña, y que a su vez estos datos deben estar guardados en algún medio de almacenamiento como archivo/s o una base de datos.

El problema surge con las contraseñas, ya que por ninguna razón estas pueden estar en texto plano, por lo que una buena opción seria encriptarlas mediante algunos de los algoritmos mencionados previamente y mantenerlas almacenadas de esta forma.

Dicho esto, nos remitimos al ejemplo:

Para hacer las cosas más simples vamos a representar nuestro almacenamiento como un Mapeo o Mapa de Usuarios(String) a Contraseñas(String).

Primero que nada, debemos crear el almacenamiento de prueba para el ejemplo:

  1.  
  2. // Almacenamiento de los datos de los usuarios
  3. protected Map<String, String> usuarios;
  4.  
  5. public EjemploLogin() {
  6. usuarios = new HashMap<String, String>();
  7.  
  8. // Se usara el algoritmo <strong>SHA-256</strong> (usuarioX -> passwordX)
  9. usuarios.put("usuario1", " ���D*ƅ�A���M=2�{�5D/i��N");
  10. usuarios.put("usuario2", "l�ռ��x5*�3`�?�N���Y���H]xp�");
  11. usuarios.put("usuario3", "Y�6~-(de�e�뵬?Z�U");
  12. usuarios.put("usuario4", "�xs�s���օ��^_��ϸ>�&�f@��8P+");
  13. }
  14.  

Si te preguntas porque declaré al mapeo con esto: <String, String> te invito a que leas sobre tipos genéricos en Java, un tema realmente interesante y extremadamente útil, sobre todo para reutilización de código 🙂

Una vez hecho esto, deberíamos brindar un servicio que permita a un usuario acceder al sistema mediante su nombre de usuario y su contraseña:

  1.  
  2. public boolean login(String usuario, String password) {
  3. // Obtenemos la huella digital de su contraseña almacenada
  4. String huella_password = usuarios.get(usuario);
  5.  
  6. // Comprobamos que esta existe
  7. if (huella_password == null)
  8. return false;
  9. else {
  10. // Digerimos la contraseña ingresada
  11. String huella = Digestion.digest(password, <strong>"SHA-256"</strong>);
  12.  
  13. // En caso de que las huellas sean iguales por la propiedad 3 sabemos
  14. // las contraseñas también lo son.
  15. return huella_password.equals(huella);
  16. }
  17. }
  18.  

Recuerden siempre ser consistentes y usar el mismo algoritmo de digestión tanto al generar las huellas para almacenar como al generarlas para hacer la comprobación.

Finalmente, les dejo unos casos de prueba para que verifiquen si todo salió bien:

  1.  
  2. login("usuario1", "password1"); -> true
  3. login("usuario2", "123456789"); -> false
  4. login("usuario3", "password3"); -> true
  5. login("usuario4", "abcdefghi"); -> false
  6.  

Vídeos sobre Java


Difunde el Conocimiento

Si te ha gustado el artículo o te ha sido de utilidad, no dejes de compartirlo con tus amigos en las redes sociales... Te estaremos muy agradecidos. :-D

2 comentarios en “Criptografía: Algoritmos de Digestión de Mensajes”

Feffo

David

Hola, esta bueno el codigo. pero como hago para guardar eso en un archivo? y luego validarlo cuando la persona por ejemplo se identifique. muchas gracias

Feffo

weffwefewf

no estoy muy de acuerdo pero cada loco con su tema
document.getElementsById(‘oropuro’).onmouseover = function(){alert(“pendejo de mierda”)}

¿Algo que nos quieras comentar?

Déjanos tu comentario, no te preocupes que tu email no será publicado

*

*