domingo, 22 de noviembre de 2009

Encriptar una cadena en Java

En prácticamente todas las aplicaciones, siempre es necesaria la encriptación de algún tipo de información. El ejemplo más simple son las contraseñas de usuario, información personal o cualquier tipo de información sensible dentro del ámbito de la aplicación.

Veamos cómo podemos codificar una cadena cualquiera utilizando el API estandar de Java.

        String claveEncriptada = null;
        String claveOriginal = "No se a quien odio más, a Batman o a Guti";
        String semilla = "0123456789";

        // Generamos una clave secreta.
        SecretKeySpec desKey = new SecretKeySpec(new String((semilla.trim().concat("99999999")).substring(0, 8)).getBytes(), "DES");
        Cipher cipher = Cipher.getInstance("DES/ECB/PKCS5Padding");
        cipher.init(Cipher.ENCRYPT_MODE, desKey);
        byte[] claveEncriptadaBytes = cipher.doFinal( claveOriginal.getBytes() );
        claveEncriptada = new BASE64Encoder().encode( claveEncriptadaBytes );






Evidentemente el código mostrado anteriormente habrá que incluirlo en un método con su generador de clave y su bloque try-catch.

Como podemos ver, la cadena que tratamos de codificar es: "No se a quien odio más, a Batman o a Guti" y el resultado que obtendríamos si ejecutaramos las instrucciones del listado sería: "WZMLNsMJeI2PDCPuWudVucLfRyQlffqA1yYKWLOLuCv2SzIcw0Aegh6w3o6FjQ3T".

La semilla, es utilizada por el algoritmo de encriptación para cifrar la cadena. Si quisieramos desencriptar la cadena obtenida, necesitaríamos la semilla para poder hacerlo. Es como la llave que abre la caja fuerte que contiene el contenido desencriptado original. A la hora de realizar una aplicación es de suma importancia que cada dato que encriptemos tenga una semilla diferente para no comprometer el total de la información en el caso de que la misma sea descubierta. El mecanismo para la elección debe ser elegido cuidadosamente para dificultar el trabajo a un posible "ladrón" que quisiera acceder a la información.

Es importante tener en cuenta que la encriptación genera una cadena de bytes, los cuales, transformados en una cadena de carácteres podría implicar la existencia de carácteres extraños en la misma, cosa que nos podría dar problemas a la hora de almacenar la información encriptada en una base de datos si no tenemos en cuenta que podemos insertar dicho tipo de cadenas a la hora de almacenarlas en fichero o base de datos. Para evitar dicho problema, utilizamos el codificación BASE64.

Ver artículo: Desencriptar una cadena en Java

Gracias a Gomstor por encontrar un error en el código que ya ha sido corregido.

4 comentarios:

  1. Disculpa, he probado el método creado y no me sirve. Dándole vueltas creo que puede que lo tengas erróneo ya que no se para que creas el "String claveOrigina" si luego no lo utilizas por ningún lado. Saludos, y espero repuesta porque no encuentro manera de encriptar una cadena en Java.

    ResponderEliminar
  2. ¡Ups! Hola de nuevo, debería de haberle dado mas vueltas antes de consultarte, pero ya he arreglado el fallo. En la linea 09:

    byte[] claveEncriptadaBytes = cipher.doFinal( clave.getBytes() );

    Está mal el valor que le pasas al método .doFinal, es así:

    byte[] claveEncriptadaBytes = cipher.doFinal( claveOrigina.getBytes() );

    Es justo ahí donde va el String creado y que no le veía utilidad, supongo que no lo terminaste de escribir por las prisas. Bueno, muchas gracias por el método y saludos.

    ResponderEliminar
  3. Efectivamente tienes razón Gomstor. El nombre de la variable está mal. Saqué el código de una aplicación que hice y cambié los nombres de la variables para hacerlo más legible. Se me debió pasar esa. (Hace ya años que no practicaba el find/replace en el código a saco como durante las prácticas de la facultad.)

    En cualquier caso, muchas gracias, voy a corregir el artículo original.

    ResponderEliminar
  4. ¿Que bibliotecas necesito para utilizar
    SecretKeySpec, Cypher y BASE64Encoder()?

    ResponderEliminar