jueves, 11 de julio de 2013

Funciones de Resumen MD5 y SHA en JAVA [aplicado a archivos]


El la publicación anterior compartí el código java para generar funciones hash a una cadena  utilizando los algoritmos MD2, MD5, SHA-1,SHA-256,SHA-384,SHA-256.

Si deseas puedes consultar  el post Funciones de Resumen MD5 y SHA en JAVA en el cual explico brevemente las funciones hash.

Para realizar las capturas de pantalla utilizo la aplicación publicada aquí: Aplicacion Java para realizar capturas de pantalla.


El código para obtener la cadena hash de un archivo es el siguiente:

import java.io.*;
import javax.crypto.*;
import javax.crypto.spec.DESKeySpec;
import java.security.*;
import java.util.*;
/*Aplicacion para generar resumenes hash de un archivo
 * @marxs7 Less is better
 * http://marxs7.blogspot.com
 */
public class HashArchivo
{
    private static String hash;
   public static String generaHash(String rutaArchivo,String algoritmo)
   {
   
    //declarar funcion de resumen
      try{
      MessageDigest messageDigest = MessageDigest.getInstance(algoritmo); // Inicializa con algoritmo seleccionado
     
      //leer fichero byte a byte 
         try{
            InputStream archivo = new FileInputStream( rutaArchivo );
            byte[] buffer = new byte[1];
            int fin_archivo = -1;
            int caracter;
       
            caracter = archivo.read(buffer);
       
            while( caracter != fin_archivo ) {
         
               messageDigest.update(buffer); // Pasa texto claro a la función resumen
               caracter = archivo.read(buffer);
            }   
       
            archivo.close();//cerramos el archivo
            byte[] resumen = messageDigest.digest(); // Genera el resumen 
            
            //Pasar los resumenes a hexadecimal
            hash = "";
            for (int i = 0; i < resumen.length; i++)
            {
               hash += Integer.toHexString((resumen[i] >> 4) & 0xf);
               hash += Integer.toHexString(resumen[i] & 0xf);
            }
          //  System.out.println("Resumen "+algoritmo+" " + hash);
         }
         //lectura de los datos del fichero
         catch(java.io.FileNotFoundException fnfe) {
         //manejar excepcion archivo no encontrado
         }
         catch(java.io.IOException ioe) {
         //manejar excepcion archivo
         }
      
      }   
      //declarar funciones resumen
      catch(java.security.NoSuchAlgorithmException nsae) {
      //manejar excepcion algorito seleccionado erroneo
      }
        return hash;//regresamos el resumen
      
   }

}


A partir de este código podemos generar una interfaz gráfica que nos permita fácilmente  obtener el valor MD5 o SHA de un archivo en formato hexadecimal.

En mi caso la interfaz es la siguiente.




Descarga











domingo, 7 de julio de 2013

Funciones de Resumen MD5 y SHA en JAVA


A las funciones hash  también se les llama funciones picadillofunciones resumen o funciones de digest. Los hash o funciones de resumen son algoritmos que consiguen crear a partir de una entrada (ya sea un texto, una contraseña o un archivo, por ejemplo) una salida alfanumérica de longitud normalmente fija que representa un resumen de toda la información que se le ha dado (es decir, a partir de los datos de la entrada crea una cadena que solo puede volverse a crear con esos mismos datos).

Las funciones hash son útiles para almacenar passwords  en bases de datos, verificar la integridad de ficheros y también se aplican en procesos de firma digital.

Para generar estas cadenas de resumen utilizaremos la clase MessageDigest de Java.

Los algoritmos que implementaremos son los siguientes:
*MD2
*MD5
*SHA-1
*SHA-256
*SHA-384
*SHA-512

En el código a continuación se  observa que se crea un arreglo con los diferentes algoritmos. El método generador de hashes es estático y recibe como parámetro la cadena que se va a resumir y un entero que corresponde al indice del arreglo de algoritmos.


import java.io.IOException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
/**
 * @author marxs7 Less is better
 */
public class Hash{
    //algoritmos
    public static String[] algoritmos={"MD2","MD5","SHA-1","SHA-256","SHA-384","SHA-512"};

    /***
     * Convierte un arreglo de bytes a String usando valores hexadecimales
     * @param digest arreglo de bytes a convertir
     * @return String creado a partir de digest
     */
    private static String toHexadecimal(byte[] digest){
        String hash = "";
        for(byte aux : digest) {
            int b = aux & 0xff;
            if (Integer.toHexString(b).length() == 1) hash += "0";
            hash += Integer.toHexString(b);
        }
        return hash;
    }

    /***
     * Encripta una cadena mediante algoritmo de resumen de mensaje.
     * @param cadena texto a encriptar
     * @param algoritmo algoritmo de encriptacion, puede ser: MD2, MD5, SHA-1, SHA-256, SHA-384, SHA-512
     * @return mensaje encriptado
     */
    public static String getHash(String cadena, int tipoAlgoritmo){
        byte[] digest = null;
        byte[] buffer = cadena.getBytes();
        try {
            MessageDigest messageDigest = MessageDigest.getInstance(algoritmos[tipoAlgoritmo]);
            messageDigest.reset();
            messageDigest.update(buffer);
            digest = messageDigest.digest();
        } catch (NoSuchAlgorithmException ex) {
            System.out.println("Error creando Hash");
        }
        return toHexadecimal(digest);
    }
    //El codigo comentado es solo para probar la funcionalidad.
     /* public static void main(String[] args){
          System.out.println("hola"+ " MD2 "+ getHash("hola",0));
          System.out.println("hola"+ " MD5 "+ getHash("hola",1));
          System.out.println("hola"+ " SHA-1 "+ getHash("hola",2));
          System.out.println("hola"+ " SHA-256 "+ getHash("hola",3));
          System.out.println("hola"+ " SHA-384 "+ getHash("hola",4));
          System.out.println("hola"+ " SHA-512 "+ getHash("hola",5));
      }*/
}

A partir de esta clase podemos crear una interfaz para hacer más fácil el uso de esta funcionalidad. En mi caso la aplicación recibe una cadena y al seleccionar algún algoritmo en el combo, muestra la cadena resultante. 

Descargar Aplicación. 18Kb
Descargar Código Fuente. Proyecto NetBeans 37 Kb