Ir al contenido principal

Java - Encriptacion / Desencriptacion de propiedades en archivo Properties

El siguiente ejemplo, permite grabar propiedades en un archivo .properties encriptadas y recuperar las mismas, estos son los pasos:

Primero se crea la clase para el manejo de las Excepciones, el archivo se llama EncriptaException, este es el código:



public class EncriptaException extends Exception{

    public EncriptaException(String message) {
        super(message);
    }

}

Luego se crea la clase encargada de la encriptación y desencriptación, se llama Encripta, este es el código:


import java.io.UnsupportedEncodingException;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;

/**
 *
 * @author mzavaleta
 */
public class Encripta {
    String clave;
    public Encripta(String clave)
    {
        this.clave=clave;
    }

    public String encriptaCadena(String mensaje) throws EncriptaException {
        byte[] rpta = encripta(mensaje);
        StringBuilder mensaje1 = new StringBuilder();
        for (int i = 0; i < rpta.length; i++) {
            String cad = Integer.toHexString(rpta[i]).toUpperCase();
            if (i != 0) {
                mensaje1.append("-");
            }
            if (cad.length() < 2) {
                mensaje1.append("0");
                mensaje1.append(cad);
            } else if (cad.length() > 2) {
                mensaje1.append(cad.substring(6, 8));
            } else {
                mensaje1.append(cad);
            }
        }
        return mensaje1.toString();
    }

    public byte[] encripta(String message) throws EncriptaException {
        try {
            final MessageDigest md = MessageDigest.getInstance("md5");
            final byte[] digestOfPassword = md.digest(clave.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");
            final byte[] cipherText = cipher.doFinal(plainTextBytes);
            return cipherText;
        } catch (NoSuchAlgorithmException ex) {
            throw new EncriptaException(ex.getMessage());
        } catch (UnsupportedEncodingException ex) {
            throw new EncriptaException(ex.getMessage());
        } catch (NoSuchPaddingException ex) {
            throw new EncriptaException(ex.getMessage());
        } catch (InvalidKeyException ex) {
            throw new EncriptaException(ex.getMessage());
        } catch (InvalidAlgorithmParameterException ex) {
            throw new EncriptaException(ex.getMessage());
        } catch (IllegalBlockSizeException ex) {
            throw new EncriptaException(ex.getMessage());
        } catch (BadPaddingException ex) {
            throw new EncriptaException(ex.getMessage());
        }
    }

    public String desencripta(String cadena) throws EncriptaException {
        String[] sBytes = cadena.split("-");
        byte[] bytes = new byte[sBytes.length];
        for (int i = 0; i < sBytes.length; i++) {
            bytes[i] = (byte) Integer.parseInt(sBytes[i], 16);
        }
        return desencripta(bytes);
    }

    public String desencripta(byte[] message) throws EncriptaException {
        try {
            final MessageDigest md = MessageDigest.getInstance("md5");
            final byte[] digestOfPassword = md.digest(clave.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");
        } catch (NoSuchAlgorithmException ex) {
            throw new EncriptaException(ex.getMessage());
        } catch (UnsupportedEncodingException ex) {
            throw new EncriptaException(ex.getMessage());
        } catch (NoSuchPaddingException ex) {
            throw new EncriptaException(ex.getMessage());
        } catch (InvalidKeyException ex) {
            throw new EncriptaException(ex.getMessage());
        } catch (InvalidAlgorithmParameterException ex) {
            throw new EncriptaException(ex.getMessage());
        } catch (IllegalBlockSizeException ex) {
            throw new EncriptaException(ex.getMessage());
        } catch (BadPaddingException ex) {
            throw new EncriptaException(ex.getMessage());
        }
    }
}




Finalmente se crea la clase Main para demostrar el uso de la encriptación/desencriptación y grabado de la propiedad encriptada:


import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;

/**
 *
 * @author mzavaleta
 */
public class Main {

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) throws IOException, EncriptaException {
        // Nombre del archivo de configuracion
        String nombreFile="config.properties";
        // Clave usada para la encriptacion
        String clave="LAS AVES VUELAN LIBREMENTE";

        String usuario="ssegadm";
        System.out.println("Usuario sin encriptar: " + usuario);

        Encripta encripta = new Encripta(clave);

        String usuarioEncriptado=encripta.encriptaCadena(usuario);
        System.out.println("Usuario encriptado: " + usuarioEncriptado);

        //Salvamos las propiedades en archivo indicado
        Properties props = new Properties();
        props.setProperty("usuario", usuarioEncriptado);
        saveProps(props, nombreFile);

        //Recuperamos el usuario desencriptado
        props = getProps(nombreFile);
        String usuarioEncriptadoRecuperado = props.getProperty("usuario");
        System.out.println("Usuario encriptado obtenido de archivo: " + usuarioEncriptadoRecuperado);

        String usuarioRecuperado = encripta.desencripta(usuarioEncriptado);
        System.out.println("Usuario obtenido de archivo: " + usuarioRecuperado);
    }

    private static Properties getProps(String nombreFile) throws FileNotFoundException, IOException {
        InputStream is = new FileInputStream(new File(nombreFile));
        Properties props = new Properties();
        props.load(is);
        is.close();
        return props;
    }

    private static void saveProps(Properties props, String nombreFile) throws IOException {
        try {
            props.store(new FileOutputStream(nombreFile), "");
        } catch (FileNotFoundException ex) {
            File file = new File(nombreFile);
            file.createNewFile();
            props.store(new FileOutputStream(nombreFile), "");
        }
    }
}

Comentarios

  1. Me funciona el codigo pero nunca veo en el archivo de propiedades el usuario que se guardo, puedes explicarme un poco más sobre esto...

    ResponderEliminar
  2. Hola Victor, el archivo config.properties se debería guardar en la ruta donde esta el .jar, si deseas puedes poner una ruta absoluta en la línea de código:

    String nombreFile="config.properties";

    Hay que tener cuidado con la sintaxis de la ruta, en caso de ser para windows o linux:

    Windows:

    String nombreFile="c:\\config.properties";

    ResponderEliminar
  3. Me arroja un error en la línea: final byte[] keyBytes = Arrays.copyOf(digestOfPassword, 24); //dice que copyOf es indefinido para el tipo Arrays

    ResponderEliminar
  4. puedes copiar el mensaje de error completo?

    ResponderEliminar
  5. Hola! este algoritmo DES tiene algun numero incial o semilla? cual es?

    ResponderEliminar
  6. Baccarat - How To Play Online - Worrione
    Baccarat is a popular card youtube mp3 game that involves the betting of numbers หาเงินออนไลน์ and 바카라 the same amount of tricks that the player expects to win. However, in Baccarat, this

    ResponderEliminar

Publicar un comentario

Entradas populares de este blog

Comparación de campos tipo NCHAR

Normalmente cuando se compara cadenas con campos del tipo NCHAR, se muestra el error: ORA-12704: character set mismatch O en español: ORA-12704: no coincide el juego de caracteres Para evitar este error se puede usar la función CSCONVERT cuya sintaxis es: CSCONVERT(cadena,'NCHAR_CS') Donde cadena es el valor que se quiere pasar a NCHAR. Veamos un ejemplo: Tenemos la tabla TABLA_NCHAR que tiene un solo campo tipo NCHAR: create table TABLA_NCHAR ( CAMPO_NCHAR NCHAR(25) ) Si intentamos hacer el siguiente query: select campo_nchar from tabla_nchar UNION SELECT 'TODOS LOS VALORES' FROM DUAL; select campo_nchar from tabla_nchar UNION SELECT 'TODOS LOS VALORES' FROM DUAL ORA-12704: character set mismatch Se mostrará el error indicado al inicio de este blog, pero si se usa la funcion el query funcionará correctamente: SQL> select campo_nchar from tabla_nchar 2 UNION 3 SELECT CSCONVERT('TODOS LOS VALORES','NCHAR_CS&

Leer Ñ en archivos desde Java

Siempre se me ha presentado este problema, cada vez que leo un archivo desde java, y este contiene caracteres como la Ñ, estos son tomado como símbolos raros: Voy a mostrar el código que ocasiona esta distorsión, el archivo "D:\temporal\prueba.txt", cuyo contenido es: PAÑALES DESCARTABLES ÚTILES DE LIMPIEZA VINO AÑEJO Y el código es el siguiente: import java.io.*; /** * * @author mzavaleta */ public class TestÑ { /** * @param args the command line arguments */ public static void main(String[] args) throws FileNotFoundException, IOException { // TODO code application logic here FileInputStream fis = new FileInputStream("D:/temporal/prueba.txt"); InputStreamReader is = new InputStreamReader(fis); BufferedReader bf = new BufferedReader(is); String linea; while ((linea = bf.readLine()) != null) { System.out.println(linea); } bf.close();

Separador decimal en Oracle

Para poder cambiar el separador decimal en Oracle, se puede usar la siguiente sentencia, suponiendo que queremos usar el punto ALTER SESSION SET NLS_NUMERIC_CHARACTERS = '. '; Para usarlo dentro de un procedimiento almacenado, se puede usar la siguiente sentencia: EXECUTE IMMEDIATE('ALTER SESSION SET NLS_NUMERIC_CHARACTERS = ''. '' ') ;