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: y su salida sería de la siguiente forma:
Hola, buen día, muchas gracias me sera de gran ayuda al trabar con bases de datos
Excelente me sirvió muchisimo
muchas gracias por tu tiempo
muy buen articulo, solo una pregunta, como genero la llave y el vector??
agradeceria la respuesta
Pues ambos no se generan automaticamente, tu mismo los creas a tu conveniencia…
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?
No se mucho de aplicaciones web, pero podrías incluir en Source de Apache Commons Codec completo. Algo rudimentario pero te podría ayudar
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!
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)
Tienes error en tu línea 62 ya que no se puede convertir de byte[] a string.
Lo solucionas con esto: byte[] enc = decodeBase64(encrypted.getBytes()); //agregando «getBytes()»
quisiera saber porque se utilizan esas excepciones.
excelente aporte, en lo personal lo ocupe para desencriptar cadenas encriptadas desde apex de sales force y viceversa
Saludos