Cómo Usar la Encriptación y Desencriptación 3DES en Java

Las aplicaciones modernas a menudo requieren una forma segura de manejar datos sensibles. Un algoritmo de encriptación popular que podrías encontrar es 3DES (Triple Data Encryption Standard). Si intentas encriptar y desencriptar cadenas utilizando 3DES en Java, podrías enfrentar problemas, como lo ilustra un problema común entre los desarrolladores: la incapacidad de desencriptar un mensaje de vuelta a su forma original. Esta publicación te ayudará a entender cómo usar correctamente la encriptación y desencriptación 3DES en Java.

El Problema

Imagina que has escrito algún código para encriptar una cadena; digamos, la cadena “kyle boon”. Después de ejecutar tu método de encriptación, intentas decodificar el resultado pero fallas en recuperar la cadena original. Muchos desarrolladores enfrentan un desafío similar, a menudo debido a un manejo inadecuado de los arreglos de bytes o por omitir pasos críticos en su código.

Un desarrollador compartió: “Cada método que escribo para codificar una cadena en Java usando 3DES no puede ser desencriptado de vuelta a la cadena original.” Este error común suele derivar de un malentendido sobre cómo funcionan los arreglos de bytes y las representaciones de cadenas en Java.

La Solución

Veamos una implementación simplificada y corregida de la encriptación y desencriptación 3DES en Java. Este código te permite encriptar una entrada de texto y luego desencriptarla fácilmente de regreso al texto original.

Explicación del Código Paso a Paso

  1. Importaciones:

    import java.security.MessageDigest;
    import java.util.Arrays;
    import javax.crypto.Cipher;
    import javax.crypto.SecretKey;
    import javax.crypto.spec.IvParameterSpec;
    import javax.crypto.spec.SecretKeySpec;
    
  2. Definición de Clase:

    public class TripleDESTest {
    
  3. Método Principal: En tu método principal, primero definirás el texto a ser encriptado.

    public static void main(String[] args) throws Exception {
        String text = "kyle boon";
        byte[] codedtext = new TripleDESTest().encrypt(text);
        String decodedtext = new TripleDESTest().decrypt(codedtext);
    
        System.out.println(codedtext);
        System.out.println(decodedtext); // "kyle boon"
    }
    
  4. Método de Encriptación: Este método codifica el mensaje de entrada utilizando el algoritmo 3DES:

    public byte[] encrypt(String message) throws Exception {
        final MessageDigest md = MessageDigest.getInstance("md5");
        final byte[] digestOfPassword = md.digest("HG58YZ3CR9".getBytes("utf-8"));
        final byte[] keyBytes = Arrays.copyOf(digestOfPassword, 24);
    
        for (int j = 0, k = 16; j < 8;) {
            keyBytes[k++] = keyBytes[j++];
        }
    
        final SecretKey key = new SecretKeySpec(keyBytes, "DESede");
        final IvParameterSpec iv = new IvParameterSpec(new byte[8]);
        final Cipher cipher = Cipher.getInstance("DESede/CBC/PKCS5Padding");
        cipher.init(Cipher.ENCRYPT_MODE, key, iv);
        final byte[] plainTextBytes = message.getBytes("utf-8");
        return cipher.doFinal(plainTextBytes);
    }
    
  5. Método de Desencriptación: Este método invierte el proceso de encriptación:

    public String decrypt(byte[] message) throws Exception {
        final MessageDigest md = MessageDigest.getInstance("md5");
        final byte[] digestOfPassword = md.digest("HG58YZ3CR9".getBytes("utf-8"));
        final byte[] keyBytes = Arrays.copyOf(digestOfPassword, 24);
    
        for (int j = 0, k = 16; j < 8;) {
            keyBytes[k++] = keyBytes[j++];
        }
    
        final SecretKey key = new SecretKeySpec(keyBytes, "DESede");
        final IvParameterSpec iv = new IvParameterSpec(new byte[8]);
        final Cipher decipher = Cipher.getInstance("DESede/CBC/PKCS5Padding");
        decipher.init(Cipher.DECRYPT_MODE, key, iv);
        final byte[] plainText = decipher.doFinal(message);
    
        return new String(plainText, "UTF-8"); // Convierte el arreglo de bytes a cadena
    }
    

Puntos Clave

  • Manejo Correcto de Arreglos de Bytes: Al decodificar, asegúrate de convertir el arreglo de bytes de nuevo a una cadena usando new String(plainText, "UTF-8") en lugar de llamar a toString() en él. Esto evita obtener una salida basura.

  • Codificación Base64: Si planeas transmitir el arreglo de bytes encriptado a través de un medio de texto, considera usar la codificación Base64. Asegúrate de decodificarlo correctamente durante la desencriptación.

  • Manejo de Excepciones: El código contiene manejo de excepciones para gestionar varios errores de encriptación, haciéndolo robusto.

Ahora tienes un enfoque claro y efectivo para usar la encriptación y desencriptación 3DES en tus aplicaciones Java. Siguiendo la explicación y los fragmentos de código anteriores, puedes implementar este poderoso método de encriptación con éxito.