27 oct 2014


En la entrada Manejo de archivos de propiedades en Java. vimos como trabajar con archivos de propiedades pero recordemos que en todo desarrollo debe de haber un grado de seguridad y mas en cuestiones de este tipo, los archivos de propiedad se almacenan en la máquina del cliente y este puede abrir fácilmente el archivo, la mayoría de usuarios finales no son expertos en informática y tal vez no les interese como funcione pero, imagina que alguna otra persona con intenciones malas y con un conocimiento medio en esta rama podría valerse de entrar en la computadora del  usuario y si has almacenado los datos para una conexión a base de datos en un archivo sin cifrar estarías exponiendo un grave fallo de seguridad al dejar eso datos a la vista de todos, así que en esta entrada aprenderemos a cifrar los datos para que no tengamos problemas con este tipo de detalles.

Para cifrar los datos nos valdremos de un API llamada Jasypt en su ultima versión 1.9.2 (http://www.jasypt.org/)  la cual se encargara de cifrar los datos que se almacenaran en el archivo de propiedades y por medio de una llave poder descifrar dichos datos.

Pasos preliminares.

Antes de adentrarnos al código es necesario realizar una configuración previa.
  • Descargar el API jasypt 1.9.2.
  • Descarga el JCE (Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy Files.) que permite usar otros otros algoritmos de cifrado. JCE.
  • Cuando hayas descargado los dos puntos anteriores copia el contenido de JCE en el directorio de JAVA_HOME\jre\lib\security
  • Y agrega las librerías de Jasypt a tu proyecto que se encuentran en jasypt-1.9.2-dist.zip\jasypt-1.9.2\lib
Listo con esto ya podremos empezar a trabajar.

  Sumergiéndonos en el oscuro mundo de la criptografía.

Para adentrarnos en este ejemplo utilizaremos el proyecto realizado en la anterior publicación llamado "propiedades" y que fue creado con NetBeans.

Agregamos las librerías de Jasypt al proyecto y empezamos por crear una clase de Java (Java Class) que llamaremos "EncrypSet" y en esta clase vamos a agregar los siguientes imports.

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Properties;
import javax.swing.JOptionPane;
import org.jasypt.encryption.pbe.PBEStringEncryptor;
import org.jasypt.encryption.pbe.StandardPBEStringEncryptor;
import org.jasypt.properties.PropertyValueEncryptionUtils;

y creamos un método "public static void" llamado "EncryProp" que contendría el cogido encargado de cifrar el archivo de propiedades.

public static void EncryProp () throws IOException {
       // Para nuestro proyecto declararemos 3 variables que son las que se encuentran en nuestro archivoo de propiedades       
        String crypnombre, crypap, crypam;
        //Creamos un FileOutputStream y le asignamos null
        FileOutputStream os = null;
        Properties props = new Properties();
        try {
            //cargamos el archivo propiedades en la variable "props" creada anteriormente
            props.load(new FileInputStream("src/propiedades/pconexion.properties"));
            // Aqui enpieza lo bueno, creamos una variable "encryptor" de tipo StandardPBEStringEncryptor() 
            PBEStringEncryptor encryptor = new StandardPBEStringEncryptor();
            // Asignamos la llave (contraseña) que nos servira para cifrar el texto y posteriormente descifrar.
            encryptor.setPassword("an_$%&LOST"); // Aqui asigna la contraseña y no la vayas a olvidar porque de otra forma no podras descifrar los datos.
            //Ahora en la variables creadas al principio asignaremos el valor cifrado, les explico este paso,
            //Llamamos a la propiedad encrypt del import PropertyValueEncryptionUtils en esta nos pide el texto a cifrar
            //y la llave para hacerlo recordaremos que con la propiedad  getProperty de la variable props podremos obtener el texto del archivo..
            crypnombre = PropertyValueEncryptionUtils.encrypt(props.getProperty("nombre"), encryptor);
            crypap = PropertyValueEncryptionUtils.encrypt(props.getProperty("apaterno"), encryptor);
            crypam = PropertyValueEncryptionUtils.encrypt(props.getProperty("amaterno"), encryptor);
            //Volvemos a guardar los datos en el archivo pero ahora ya cifrados
            props.setProperty("nombre", crypnombre);
            props.setProperty("apaterno", crypap);
            props.setProperty("amaterno", crypam);
             //Con el FileOutputStream lo guardamos
             os = new FileOutputStream("src/propiedades/pconexion.properties");
             props.store(os, "Datos Encriptados."); 
           } catch(IOException ioe){ 
               JOptionPane.showMessageDialog(null,"Error al crear el archivo de Propiedades encriptado.\nInfo: "+ioe,"Creacion de Archivo.",JOptionPane.ERROR_MESSAGE);
            }    
    }

Con esto terminamos la Clase Java "EncrypSet" y pasamos al formulario llamado "principal" de nuestro proyecto.

En este formulario se encuentran 2 botones entraremos a la propiedad "ActionPerformed" del botón "guardar" y agregaremos este código.

private void b_guardarActionPerformed(java.awt.event.ActionEvent evt) { 
        //Creamos la variable props                                         
        Properties prop= new Properties();
        //validamos que ningun dato nos falte en este caso que ningun Jtextfield este vacio
        if(t_nombre.getText().isEmpty() || t_ap.getText().isEmpty() || t_am.getText().isEmpty()){
        //si alguno esta vacio manda el mensaje    
        JOptionPane.showMessageDialog(null,"Faltan datos para el archivo de configuración.","Datos faltantes.",JOptionPane.ERROR_MESSAGE);
        }else{
            //Si todo esta bien guardamos el contenido de cada uno en el archivo de propiedades
            propiedades.setProperty("nombre", t_nombre.getText());
            propiedades.setProperty("apaterno", t_ap.getText());
            propiedades.setProperty("amaterno", t_am.getText());
           try {
                FileOutputStream os = new FileOutputStream("src/propiedades/pconexion.properties");
                propiedades.store(os, "Nombre del Usuario.");
                // Y aqui es donde viene lo interesante llamamos a la clase Java que creamos con el metodo EncryProp
                EncrypSet.EncryProp();
                //Vaseamos los Jtextfields
                t_nombre.setText("");
                t_ap.setText("");
                t_am.setText("");
           } catch(IOException ioe){ 
               JOptionPane.showMessageDialog(null,"Error al crear el nuevo archivo de Propiedades.\nInfo: "+ioe,"Creacion de Archivo.",JOptionPane.ERROR_MESSAGE);
            }               
        }
    }    

A estas alturas si nosotros ejecutamos el formulario "principal" y agregamos datos al archivo de propiedades, se agregarian cifrados pero no podriamos ver en realidad lo que ingresamos.


Como vemos en la imagen de arriba los datos aparecen cifrados con un formato de "ENC(muchas letras y simbolos)" ejemplo:  ENC(acAc3Hl5QxaKwEnXNNlRQQ==) y con esto nuestra informacion queda protegida ante usuarios curiosos o malintencionados; despues de esto te preguntaras bueno y si quiero saber que es lo que hay detras de ese cifrado y ver los datos reales ¿Como lo descifro?.

Para eso es este código, primero agregamos los imports necesarios y despues entramos al atributo "ActionPerformed" del boton "Cargar".

//Agregamos estos imports
import org.jasypt.encryption.pbe.PBEStringEncryptor;
import org.jasypt.encryption.pbe.StandardPBEStringEncryptor;
import org.jasypt.properties.EncryptableProperties;

Y después.

private void b_cargarActionPerformed(java.awt.event.ActionEvent evt) {                                         
           try {
            //Creamos una variable "encryptor" del tipo StandardPBEStringEncryptor()
            PBEStringEncryptor encryptor = new StandardPBEStringEncryptor();
            //a esta variable le asignamos la llave o cntraseña utilizada para cifrar los datos 
            encryptor.setPassword("an_$%&LOST");
            //Creamos una variable "settin" del tipo EncryptableProperties y agregamos "encryptor" que contiene la llave
            Properties settin = new EncryptableProperties (encryptor);
            //apartir de aqui cargamos y obtenemos los datos normalmente como lo hacemos
            settin.load(new FileInputStream("src/propiedades/pconexion.properties"));
            propiedades.load(new FileInputStream("src/propiedades/pconexion.properties"));
            //cargamos los datos ya descifrados en los string nom,ap y am
            nom = settin.getProperty("nombre");
            ap = settin.getProperty("apaterno");
            am = settin.getProperty("amaterno");
            //los mostramos en el jtextarea
            ta_ver.setText("");
            ta_ver.append("------------Datos Cifrados---------------");
            ta_ver.append(System.getProperty("line.separator"));
            ta_ver.append("Nombre = " + propiedades.getProperty("nombre"));
            ta_ver.append(System.getProperty("line.separator")); // Esto para el salto de línea 
            ta_ver.append("A Paterno = " + propiedades.getProperty("apaterno"));
            ta_ver.append(System.getProperty("line.separator")); // Esto para el salto de línea 
            ta_ver.append("A Materno = " + propiedades.getProperty("amaterno"));
            ta_ver.append(System.getProperty("line.separator")); // Esto para el salto de línea 
            ta_ver.append("------------Datos Descifrados---------------");
            ta_ver.append(System.getProperty("line.separator"));
            ta_ver.append("Nombre = " + nom);
            ta_ver.append(System.getProperty("line.separator")); // Esto para el salto de línea 
            ta_ver.append("A Paterno = " + ap);
            ta_ver.append(System.getProperty("line.separator")); // Esto para el salto de línea 
            ta_ver.append("A Materno = " + am);

          }catch (FileNotFoundException e) {
            JOptionPane.showMessageDialog(null,"Error, no existe el archivo de configuracion.\nInfo: "+e,"Error de archivo de propiedades.",JOptionPane.ERROR_MESSAGE);
        } catch (IOException e) {
            JOptionPane.showMessageDialog(null,"Error, no se puede leer archvio de configuracion.\nInfo: "+e,"Error de archivo de propiedades.",JOptionPane.ERROR_MESSAGE);
        }
    }     

Ejecutando el archivo he ingresando datos esto es lo que obtenemos.


Así Terminamos esta entrada espero les gustara, anexo el proyecto ya modificado con este código por si gustan ocuparlo y mas adelante ocuparemos este método para realizar conexiones a MySQL.



0 comentarios:

Publicar un comentario

Comentar siempre es bueno.
Dejanos saber que piensas sobre este tema.

Powered By Blogger
Subscribe to RSS Feed Follow me on Twitter!