Encriptación DES

   Luego de un largo tiempo sin publicar en el blog vuelvo con una entrada interesante, últimamente estoy muy de lleno en lo que es el tema de la seguridad informática, es un punto de vital importancia para nosotros, lo desarrolladores, quienes queremos que nuestros programas no sean solo seguros, sino que brindemos un sistema robusto y con acceso controlado al mismo....

   Encriptar un archivo para ocultar su contenido es algo muy común en la mayoría de los programas de hoy en día, la mayoría los utiliza para ocultar parámetros, configuraciones, limitaciones, entre otros. Y ahora debemos entrar un poco en teoría para luego ver en que consiste el algorítmo.

   En los años 70's los expertos en informática y los asesores en materia de defensa y seguridad nacional de los Estados Unidos, de forma paradójica concluyeron que en una sociedad democrática y libre no toda la información debe estar disponible al público, y no toda persona debe tener acceso a cierta información considerada muy crucial, lo cual redunda en beneficio de la adecuada marcha de la vida en sociedad. Por eso se recomendó el uso de la encriptación para mantener bajo clasificación ciertos documentos muy importantes y para preservar la confidencialidad de ciertas comunicaciones privadas entre las entidades gubernamentales, los altos mandos de las fuerzas militares, las agencias de seguridad (CIA, FBI, policía, etc.), las entidades financieras o bancarias, etc.


   No voy a entrar en tanta teoría porque no es lo mismo (aunque si tuve que leerme bastante para comprender de que va todo)... Para mas información acerca de la encriptación DES (Data Encryption Standard o Encriptación de Data Estandar en español), puedes ver este enlace: Encriptación DES.

   Y ahora si, vamos con el código para ver como va esto, primero, la clase para la encriptar / desencriptar:
import java.io.UnsupportedEncodingException;
import java.security.spec.AlgorithmParameterSpec;
import java.security.spec.KeySpec;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.PBEKeySpec;
import javax.crypto.spec.PBEParameterSpec;

public class DES {

    Cipher ecipher;
    Cipher dcipher;

    byte[] salt = {
        (byte)0xA9, (byte)0x9B, (byte)0xC8, (byte)0x32,
        (byte)0x56, (byte)0x35, (byte)0xE3, (byte)0x03
    };

    int iterationCount = 19;

    DES(String passPhrase) {
        try {
            KeySpec keySpec = new PBEKeySpec(passPhrase.toCharArray(), salt, iterationCount);
            SecretKey key = SecretKeyFactory.getInstance(
                "PBEWithMD5AndDES").generateSecret(keySpec);
            ecipher = Cipher.getInstance(key.getAlgorithm());
            dcipher = Cipher.getInstance(key.getAlgorithm());

            AlgorithmParameterSpec paramSpec = new PBEParameterSpec(salt, iterationCount);

            ecipher.init(Cipher.ENCRYPT_MODE, key, paramSpec);
            dcipher.init(Cipher.DECRYPT_MODE, key, paramSpec);
        } catch (java.security.InvalidAlgorithmParameterException e) {
        } catch (java.security.spec.InvalidKeySpecException e) {
        } catch (javax.crypto.NoSuchPaddingException e) {
        } catch (java.security.NoSuchAlgorithmException e) {
        } catch (java.security.InvalidKeyException e) {
        }
    }

    public String encrypt(String str) {
        try {
            byte[] utf8 = str.getBytes("UTF8");

            byte[] enc = ecipher.doFinal(utf8);

            return new sun.misc.BASE64Encoder().encode(enc);
        } catch (javax.crypto.BadPaddingException e) {
        } catch (IllegalBlockSizeException e) {
        } catch (UnsupportedEncodingException e) {
        } catch (java.io.IOException e) {
        }
        return null;
    }

    public String decrypt(String str) {
        try {
            byte[] dec = DatatypeConverter.parseBase64Binary(str);

            byte[] utf8 = dcipher.doFinal(dec);

            return new String(utf8, "UTF8");
        } catch (javax.crypto.BadPaddingException e) {
        } catch (IllegalBlockSizeException e) {
        } catch (UnsupportedEncodingException e) {
        } catch (java.io.IOException e) {
        }
        return null;
    }
}

   Luego el "Front-End" o interfáz gráfica que nos simplifica la vida un montón:
import javax.swing.*;
import java.awt.event.*;
import java.awt.GridLayout;

class Encriptar extends JFrame implements ActionListener {

 //carga del algoritmo
 DES clase_encript = new DES("carlitoxenlaweb");
 JLabel etiqueta = new JLabel("Probando DES: Carlitox en la Web");

 //cajas de texto
 JTextArea texto_desencriptado = new JTextArea(" ");
  JScrollPane scroll_desencript=new JScrollPane(texto_desencriptado,JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
 JTextArea texto_encriptado = new JTextArea(" ");
  JScrollPane scroll_encript=new JScrollPane(texto_encriptado,JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);

 //botones
 JButton encriptar = new JButton ("Encriptar");
 JButton desencriptar = new JButton ("Desencriptar");

 Encriptar() {

  //el diseño
  setLayout(new GridLayout(0,2));

  //los elementos
  add(scroll_desencript);
  add(scroll_encript);
  add(encriptar);
  add(desencriptar);
  add(etiqueta);

  //implementamos la accion
  encriptar.addActionListener(this);
  desencriptar.addActionListener(this);

  //Cerrar Ventana
  addWindowListener(new WindowAdapter() {
   public void windowClosing(WindowEvent we) {
     System.exit(0);
    }
  });

  setTitle("Encriptación DES Carlitox en la Web");
     setSize(800,600);
  setVisible(true);

 }


 //el escucha o listener
 public void actionPerformed(ActionEvent evt) {
  if(evt.getSource()==encriptar)
    texto_encriptado.setText(clase_encript.encrypt(texto_desencriptado.getText()));

  if(evt.getSource()==desencriptar)
    texto_desencriptado.setText(clase_encript.decrypt(texto_encriptado.getText()));
 }

 //la clase principal
 public static void main (String []args) {
  new Encriptar();
 }
}

   La parte realmente importante de todo esto esta en esta línea:
byte[] salt = {
        (byte)0xA9, (byte)0x9B, (byte)0xC8, (byte)0x32,
        (byte)0x56, (byte)0x35, (byte)0xE3, (byte)0x03
    };

   Es donde se define la posición y ubicación de cada uno de los caracteres en el arreglo de bytes para la llave. Para no generar claves dinámicas como lo explica el API de Java, colocamos una personalizada en esta línea de código y la enviamos a la clase como clave base para el algoritmo:
DES clase_encript = new DES("AQUI LA CLAVE");

   Una vez ya tiene la clave la instanciamos con el tipo de seguridad (en este caso "PBE / MD5 / DES") inicializamos las variables para encriptar / desencriptar a partir del algoritmo generado por la instancia de la llave o clave que le enviamos anteriormente a la clase:
ecipher = Cipher.getInstance(key.getAlgorithm());
dcipher = Cipher.getInstance(key.getAlgorithm());

AlgorithmParameterSpec paramSpec = new PBEParameterSpec(salt, iterationCount);

ecipher.init(Cipher.ENCRYPT_MODE, key, paramSpec);
dcipher.init(Cipher.DECRYPT_MODE, key, paramSpec);

   NOTA: guardamos la codificación todo el tiempo en UTF-8 para evitar conflicto entre sistemas y lectura de caracteres.

   Y con esto ya tenemos un algoritmo de encriptación DES, el cual podemos combinar con la lectura de archivos para cargar parámetros y valores ocultos en nuestro sistema sin que el usuario deba enterarse de cuales son estos valores. También podemos agregarle una opción de "Abrir" y "Guardar" en un menú para no tener que copiar y pegar todo el tiempo la llave generada.

   Ya por último les dejo el siguiente dato extraido de Eye In The Sky:
   En enero de 1998 la RSA Data Security convocó al concurso DES Challenge II-1, ofreciendo esta vez el premio de $10.000 dólares para quien en menos tiempo que el vencedor del concurso anterior pudiera descifrar un mensaje encriptado mediante el sistema DES de 56 bits. En esa ocasión el concurso fue ganado en sólo 41 días por un grupo de miles de PCs de voluntarios y colaboradores de Distributed.Net, una organización mundial sin ánimo de lucro dedicada al avance de la informática. El mensaje descifrado decía lo siguiente: «The secret message is: Many hands make light work» (Muchas manos hacen el trabajo ligero).