JAVA Encriptar y Desencriptar texto AES CBC 128 bits

Código JAVA Encriptar y Desencriptar Texto usando el algoritmo AES con Cifrado por bloques CBC de 128 bits, no voy a entrar en mucho detalle, pero esta clase tiene los enlaces en los comentarios los enlaces necesarios para profundizar en el tema y así poder entender la teoría del mismo.

Ojo descarguense la librería Apache Commons Codec

package encrypt;

import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import static org.apache.commons.codec.binary.Base64.decodeBase64;
import static org.apache.commons.codec.binary.Base64.encodeBase64;

/**
 * @version 1.0
 * Clase que contiene los métodos encrypt y descrypt, cuyos objetivos son
 * encriptar y desencriptar respectivamente, utilizando los algoritmos y codificación
 * definidas en las variables estáticas alg y cI.
 * Requiere la librería Apache Commons Codec
 * @see <a href="http://commons.apache.org/proper/commons-codec/">Apache Commons Codec</a>
 * @see <a href="http://docs.oracle.com/javase/8/docs/api/javax/crypto/Cipher.html">javax.crypto Class Cipher</a>
 * @see <a href="http://es.wikipedia.org/wiki/Advanced_Encryption_Standard">WikiES: Advanced Encryption Standard</a>
 * @see <a href="http://es.wikipedia.org/wiki/Criptograf%C3%ADa">WikiES: Criptografía</a>
 * @see <a href="http://es.wikipedia.org/wiki/Vector_de_inicializaci%C3%B3n">WikiES: Vector de inicialización</a>
 * @see <a href="http://es.wikipedia.org/wiki/Cifrado_por_bloques">WikiES: Cifrado por bloques</a>
 * @see <a href="http://www.linkedin.com/in/jchinchilla">Julio Chinchilla</a>
 * @author Julio Chinchilla
 */
public class StringEncrypt {

    // Definición del tipo de algoritmo a utilizar (AES, DES, RSA)
    private final static String alg = "AES";
    // Definición del modo de cifrado a utilizar
    private final static String cI = "AES/CBC/PKCS5Padding";

    /**
     * Función de tipo String que recibe una llave (key), un vector de inicialización (iv)
     * y el texto que se desea cifrar
     * @param key la llave en tipo String a utilizar
     * @param iv el vector de inicialización a utilizar
     * @param cleartext el texto sin cifrar a encriptar
     * @return el texto cifrado en modo String
     * @throws Exception puede devolver excepciones de los siguientes tipos: NoSuchAlgorithmException, InvalidKeyException, InvalidAlgorithmParameterException, IllegalBlockSizeException, BadPaddingException, NoSuchPaddingException
     */
    public static String encrypt(String key, String iv, String cleartext) throws Exception {
            Cipher cipher = Cipher.getInstance(cI);
            SecretKeySpec skeySpec = new SecretKeySpec(key.getBytes(), alg);
            IvParameterSpec ivParameterSpec = new IvParameterSpec(iv.getBytes());
            cipher.init(Cipher.ENCRYPT_MODE, skeySpec, ivParameterSpec);
            byte[] encrypted = cipher.doFinal(cleartext.getBytes());
            return new String(encodeBase64(encrypted));
    }

    /**
     * Función de tipo String que recibe una llave (key), un vector de inicialización (iv)
     * y el texto que se desea descifrar
     * @param key la llave en tipo String a utilizar
     * @param iv el vector de inicialización a utilizar
     * @param encrypted el texto cifrado en modo String
     * @return el texto desencriptado en modo String
     * @throws Exception puede devolver excepciones de los siguientes tipos: NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, InvalidAlgorithmParameterException, IllegalBlockSizeException
     */
    public static String decrypt(String key, String iv, String encrypted) throws Exception {
            Cipher cipher = Cipher.getInstance(cI);
            SecretKeySpec skeySpec = new SecretKeySpec(key.getBytes(), alg);
            IvParameterSpec ivParameterSpec = new IvParameterSpec(iv.getBytes());
            byte[] enc = decodeBase64(encrypted);
            cipher.init(Cipher.DECRYPT_MODE, skeySpec, ivParameterSpec);
            byte[] decrypted = cipher.doFinal(enc);
            return new String(decrypted);
    }

}

EJEMPLO DE CLASE CONSUMIDORA

package encrypt;

/**
 * Clase que consume los métodos de la clase StringEncrypt
 * @author Julio Chinchilla
 */
public class Main {

 public static void main(String[] args) throws Exception {
 String key = "92AE31A79FEEB2A3"; //llave
 String iv = "0123456789ABCDEF"; // vector de inicialización
 String cleartext = "hola";
 System.out.println("Texto encriptado: "+encrypt.StringEncrypt.encrypt(key, iv,cleartext));
 System.out.println("Texto desencriptado: "+encrypt.StringEncrypt.decrypt(key, iv,encrypt.StringEncrypt.encrypt(key, iv,cleartext)));
 }

}

El ejemplo anterior tiene como structura la siguiente: Sin título y su salida sería de la siguiente forma: enc

14 comentarios sobre “JAVA Encriptar y Desencriptar texto AES CBC 128 bits

  1. hola, hace tiempo que no toco java, tengo una aplicación corriendo en tomcat 4.1 (un poco antiguo) y me da error a la hora de incluir el apache commons code.
    primero intento hacer y compilar la clase StringEncrypt para incluirla como un <jsp:useBean, pero me da error en esta línea (import static org.apache.commons.codec.binary.Base64.decodeBase64).
    como te he dicho hace tiempo que no estoy con java, no sé los pasos a seguir o si estoy haciendo lo correcto. ¿podías ayudarme?

  2. Hola!!
    Muchas gracias!! Esta muy bien, gracias por compartir.
    Podrias explicar un poco profundizado que es/que hace/Para que se necesita;
    -SecretKeySpec
    -IvParameterSpec
    -decodeBase64

    Gracias!

    1. SecretKeySpec: Es un objeto que especifica una clave secreta de manera independiente del proveedor (entiendase en este caso el tipo de cifrado), como puedes ver en el constructor recibe la clave en forma de bytes y tambien recibe el tipo de algoritmo.
      IVParameterSpec: Este objeto simplemente especifica el vector de inicialización, en palabras de la wikipedia: En criptografía, un vector de inicialización (conocido por sus siglas en inglés IV) es un bloque de bits que es requerido para permitir un cifrado en flujo o un cifrado por bloques, en uno de los modos de cifrado, con un resultado independiente de otros cifrados producidos por la misma clave. El tamaño del IV dependen del algoritmo de cifrado y del protocolo criptográfico y a menudo es tan largo como el tamaño de bloque o como el tamaño de la clave. Viendolo desde un punto de vista sencillo puedes visualizarlo como que el tipo de encriptación usa 2 claves, la clave principal y el vector de inicialización.
      decodeBase64 y/o encodeBase64: es para decodificar o codificar basado en el sistema Base64, en palabras de la wikipedia: Base 64 es un sistema de numeración posicional que usa 64 como base. Es la mayor potencia de dos que puede ser representada usando únicamente los caracteres imprimibles de ASCII. Esto ha propiciado su uso para codificación de correos electrónicos, PGP y otras aplicaciones. Todas las variantes famosas que se conocen con el nombre de Base64 usan el rango de caracteres A-Z, a-z y 0-9 en este orden para los primeros 62 dígitos, pero los símbolos escogidos para los últimos dos dígitos varían considerablemente de unas a otras. Otros métodos de codificación como UUEncode y las últimas versiones de binhex usan un conjunto diferente de 64 caracteres para representar 6 dígitos binarios, pero estos nunca son llamados Base64. En terminos sencillos se usa Base64 porque estamos tratando con caracteres (Strings)

  3. excelente aporte, en lo personal lo ocupe para desencriptar cadenas encriptadas desde apex de sales force y viceversa

    Saludos

Deja un comentario

Este sitio utiliza Akismet para reducir el spam. Conoce cómo se procesan los datos de tus comentarios.