Mostrando entradas con la etiqueta encriptación. Mostrar todas las entradas
Mostrando entradas con la etiqueta encriptación. Mostrar todas las entradas

martes, 18 de mayo de 2021

Como encriptar propiedades con Jasypt

Hoy vamos a ver una interesante herramienta que nos permitirá encriptar nuestras propiedades. Es una mala praxis común, que se suban a  repositorios de códigos o directamente se pongan 'a fuego' contraseñas a utilizar por nuestro código Java. Para evitar esto, podemos utilizar Jasypt, el cual como veremos es facil de usar y nos da múltiples formas de configuración y encriptación. 

A lo largo del post, nos centraremos en como usarlo en base a su posible uso con la encriptación de propiedades. Que es el lugar donde habitualmente almacenamos información sensible. Pero antes de ver un ejemplo de como implementar, veremos cuales son las posibles opciones que nos provee Jasypt. 

Para empezar y siempre que hablemos de encriptar String, tendremos cuatro posibles opciones:

  • BasicPasswordEncryptor: Nos permite hacer una encriptación del código sencilla y poco costosa. 
  • StrongPasswordEncryptor: Nos permite hacer una encriptación más compleja pero también más costosa a nivel de consumo de CPU. 
  • StandardPBEStringEncryptor: Nos permite hacer encriptación bidirecional, en la cual podremos indicar distintos valores: el algoritmo a utilizar, el IvGenerator y lo más importante la clave a partir de la cual encriptar y desencriptar.
  • PooledPBEStringEncryptor: Muy similar al anterior, solo que además crear un pool de StandardPBEStringEncryptor y por tanto mejora el rendimiento a la hora de utilizarlo. Muy util si vamos a utilizarlo mucho. 

Su uso es realmente básico, y lo podremos ver más adelante. Pero igual necesitamos aclarar un par de conceptos antes. Sobre todo en lo referente a los StandardPBEStringEncryptor que permiten una mayor configuración. 

  • Clave maestra

Por un lado, tenemos que indicar cual es la clave sobre la que partiremos para poder realizar esta encriptacion/desencriptación. Esta puede se la que deseemos, siempre y cuando cumpla con unos mínimos de seguridad en cuanto a tipo de caracteres y mínimo de longitud. Pero aquí, lo más importante puede ser como almacenamos esa contraseña. Porque estamos ante la misma disyuntiva de tener que poner una clave en nuestro código. Para ello, la mejor solución, siguiendo la metodología de 12 factor, es almacenar dicha clave en una variable del entorno. Si usamos Linux podemos crear dicha variable en el fichero /etc/environment (pero con cuidado, que necesitamos reiniciar luego el sistema para que se tenga en cuenta). Y luego obtenerla fácilmente en nuestro código Java. 

private String PBES_PWD = System.getenv("JASYPT_PWD");

  • Algoritmo de encriptación
Este es un valor opcional, pero no esta demás indicarlo y nos permitirá seleccionar el algoritmo de encriptación con el cual nos sintamos más cómodos. Este algoritmo dependerá de nuestra JVM. Y si no estamos seguro de cual usar o de cuales tenemos disponibles. Podemos utilizar el siguiente código Java que nos indicará los posibles valores.

for (Provider provider : Security.getProviders()) {
	log.info("Provider: " + provider.getName());
	for (Provider.Service service : provider.getServices()) {
		log.info("  Algorithm: " + service.getAlgorithm());
	}
}
  • IvGenerator

Los algoritmos de tipo PBEWithDigestAndAES que son soportados por Java Cryptography Extension aka JCE, necesitan de un vector de inicialización aka IV. Este además debe de ser aleatorio y usado una única vez. Para ello Jasypt proporciona la clase RandomIvGenerator.

A continuación veremos un pequeño trozo de código que incluye las distintas configuraciones, para que se vean lo sencillas que son de usar. A tener en cuenta que las clases StandardPBEStringEncryptor y PooledPBEStringEncryptor tienen una configuración por defecto, por lo que no es necesario incluir todos los parámetros, pero al menos si hay que incluir la clave maestra. 

private String toEncrypt = "pAsSw0Rd";
private String PBES_PWD = System.getenv("JASYPT_PWD");
private Long init;
private Long end;

@Test
public void test() {
    log.info("basic");
    BasicPasswordEncryptor passwordEncryptor = new BasicPasswordEncryptor();
    String encryptedPassword = passwordEncryptor.encryptPassword(toEncrypt);
    assertThat(passwordEncryptor.checkPassword(toEncrypt, encryptedPassword), equalTo(true));

    log.info("strong");
    StrongPasswordEncryptor passwordEncryptor = new StrongPasswordEncryptor();
    String encryptedPassword = passwordEncryptor.encryptPassword(toEncrypt);
    assertThat(passwordEncryptor.checkPassword(toEncrypt, encryptedPassword), equalTo(true));

    log.info("standarPbes");
    StandardPBEStringEncryptor encryptor = new StandardPBEStringEncryptor();
    encryptor.setPassword(PBES_PWD); // we HAVE TO set a password
    String encryptedPassword = encryptor.encrypt(toEncrypt);
    assertThat(encryptor.decrypt(encryptedPassword), equalTo(toEncrypt));

    log.info("pooledPbes_configure");
    PooledPBEStringEncryptor encryptor = new PooledPBEStringEncryptor();
    encryptor.setAlgorithm("PBEWithHmacSHA512AndAES_256");
    encryptor.setIvGenerator(new RandomIvGenerator());
    encryptor.setPoolSize(4);
    encryptor.setPassword(PBES_PWD); // we HAVE TO set a password
    String encryptedPassword = encryptor.encrypt(toEncrypt);
    assertThat(encryptor.decrypt(encryptedPassword), equalTo(toEncrypt));
}

Y si comparamos lo tiempos, tendremos la siguiente salida. 

BasicPasswordEncryptor: 3 ms
StrongPasswordEncryptor: 99 ms
StandardPBEStringEncryptor: 7ms
PooledPBEStringEncryptor without configuration: 3ms
PooledPBEStringEncryptor with configuration: 8ms

Y ahora que sabemos el uso básico, vamos a aplicarlo a un fichero de propiedades que tengamos en nuestra aplicación. Para poder hacer uso de ello, solo tendremos que realizar estos pasos:

  • Crear un objeto de tipo StringEncryptor tal y como hemos visto anteriormente. 
  • Crear un objeto de tipo Properties con ayuda de la clase EncryptableProperties. A esta clase le deberemos pasar el objeto StringEncryptor creado en el punto anterior.
  • Almacenar las propiedades encriptadas encapsuladas entre ENC( ).
Ejemplo de clase de utilidad:

@Log4j2
public class EncryptorHelper {
	@Getter
	private static EncryptorHelper INSTANCE = new EncryptorHelper();
	Properties props = null;
	private EncryptorHelper() {
		PooledPBEStringEncryptor encryptor = new PooledPBEStringEncryptor();
		encryptor.setAlgorithm("PBEWithHmacSHA512AndAES_256");
		encryptor.setIvGenerator(new RandomIvGenerator());
		encryptor.setPoolSize(4);
		encryptor.setPassword(System.getenv("JASYPT_PWD"));
		props = new EncryptableProperties(encryptor);
		try {
			props.load(new FileInputStream("src/main/resources/configuration.properties"));
		} catch (IOException except) {
			log.error("Error loading configuration.properties", except);
		}
	}

	public String getProperty(final String key) {
		return props.getProperty(key);
	}
}

Ejemplo de fichero de propiedades donde el usuario no esta encriptado y si el password:

datasource.usr=root
datasource.pwd=ENC(xwg7loJbeovRKn4R710cjEKyTBfwQV/PNKgPHZdQoOQ1AQ9W/UwfjnhRyHUyuKdD)

Hasta aquí hemos podido ver como funcionaría con una aplicación normal. Pero también veremos como hacer uso del mismo en una aplicación de Spring Boot. 

Ya tenemos los conocimientos básicos de Jasypt y como siempre hacer funcionar cualquier librería con Spring será algo sencillo. Aunque en este caso tendremos que hacer uso de una librería no desarrollada por la propia Spring sino por un usuario, Ulises Bocchio. Pero en cuatro sencillos pasos podremos tener nuestra aplicación de Spring con propiedades encriptadas. 

Primero debemos incluir las dependencias correspondientes para Spring. Las cuales se pueden facilitar si nuestro proyecto tiene como padre a spring-boot-starter-parent. Pero aparte deberemos incluir la dependencia que acople Jasypt con Spring, y ha sido realizada por el desarrollador externo:

<dependency>
    <groupId>com.github.ulisesbocchio</groupId>
    <artifactId>jasypt-spring-boot</artifactId>
    <version>3.0.3</version>
</dependency>

La segunda parte será la de añadir la anotación @EnableEncryptableProperties a nuestra clase principal de configuración:

@SpringBootApplication
@ComponentScan(basePackages = { "es.home.example.encrypt" })
@EnableEncryptableProperties
public class Aplicacion {
	public static void main(final String[] args) {
		SpringApplication.run(Aplicacion.class, args);
	}
}

La tercera parte será añadir la configuración de Jasypt en el fichero de configuración de Spring, application.properties. En ella podremos indicar el algoritmo de encriptación o la clase de generación IV. Aparte por supuesto de nuestras variables encriptadas: 

jasypt.encryptor.algorithm=PBEWithHmacSHA512AndAES_256
jasypt.encryptor.iv-generator-classname=org.jasypt.iv.RandomIvGenerator

spring.datasource.jdbc-url=jdbc:oracle:thin:@localhost:1521/XE
spring.datasource.username=root
spring.datasource.password=ENC(xwg7loJbeovRKn4R710cjEKyTBfwQV/PNKgPHZdQoOQ1AQ9W/UwfjnhRyHUyuKdD)
spring.datasource.driver-class-name=oracle.jdbc.OracleDriver

Por último las propiedades tal y como hicimos en el ejemplo anterior. Y podriamos obtener los valores del fichero configuration.properties de la siguiente forma:

@ConfigurationProperties(prefix = "datasource")
@Configuration("configuration")
@Data
public class ConfigurationPropService {
	private String usr;
	private String pwd;
}

O si los almacenamos en el application.properties, los podriamos obtener de la siguiente forma: 

@Service
@Getter
public class AppPropertyService {
	@Value("${spring.datasource.username}")
	private String usr;
	@Value("${spring.datasource.password}")
	private String pwd;
}

Para que funcionase, debemos pasar la clave maestra de dos diferentes de formas:

  • A través de una variable de entorno denominada JASYPT_ENCRYPTOR_PASSWORD.
  • A través de un argumento de la JVM o Maven denominado jasypt_encryptor_password

Esta misma solución la podemos adoptar para una aplicación de Apache Camel pero que este gestionada por Spring Boot. 

Como vemos, es una rápida y sencilla solución para evitar tener nuestro código con contraseñas sensibles. Como único inconveniente puede ser el que nuestras propiedades no se encuentren sincronizadas y necesitemos de reiniciar nuestra aplicación si queremos cambiarlas. Pero para eso ya veremos que hay soluciones como Hashicorp Vault o Apache Zookeeper.

Por último si quieres probarlo, aquí tienes el código. 

miércoles, 15 de enero de 2020

Maven: Encriptar contraseñas

Una práctica habitual es crear perfiles para la configuración de distintos entornos en una aplicación maven. Y como es normal dentro de esta configuración es posible que vayan contraseñas. Hoy mostraremos como encriptar contraseñas en Maven y un par de consejos para el correcto manejo de las mismas.

Para empezar debemos generar una clave maestra. Esta la crearemos a través del siguiente comando:

mvn --encrypt-master-password

Al introducirlo nos pedirá que introduzcamos nuestra clave maestra. Y nos la devolverá códificada.

{Q0eIoh2W24Hovj4oE0pXgObO3zHOXn/gvQC1gMFoI=}

Esta clave maestra, con el siguiente formato, la incluiremos en el fichero .m2/settings-security.xml, (que como sabéis se encuentra dentro de la carpeta home del usuario).

<settingsSecurity>
  <master>{Q0eIoh2W24Hovj4oE0pXgObO3zHOXn/gvQC1gMFoI=}</master>
</settingsSecurity>

Ahora ya podremos encriptar contraseñas a través del comando --encrypt-password o -ep

mvn -ep root
{d/vIFp4AAAH2yHgBmc4A5NHaUdhOQWon9htDpHZBY=}

Pero aquí viene un pequeño pero. Estas contraseñas generadas las podremos incluir solamente en el fichero settings.xml (ubicado también en la carpeta m2). ¿Por qué en el settings.xml y no directamente en el pom.xml?. Pues porque es una best practices, y la sección server del settings.xml se creó para eso mismo: gestionar información sensible sobre servidores, la cual no debería esta navegando libremente. Por tanto nuestra configuración quedaría así:

<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0" 
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0                         https://maven.apache.org/xsd/settings-1.0.0.xsd">
  <localRepository />
  <interactiveMode />
  <offline />
  <pluginGroups />
  <servers>
    <server>
      <id>mysql-local</id>
      <username>root</username>
      <password>{d/vIFp4AAAH2yHgBmc4A5NHaUdhOQWon9htDpHZBY=}</password>
    </server>
  </servers>
  <mirrors />
  <proxies />
  <profiles /> 
  <activeProfiles />
</settings>

Y con esto ya tendríamos nuestras contraseñas relativas a los servidores codificadas y listas para usar con maven... ¿Pero como lo uso dentro del pom.xml? Esto parece una verdad a medias...

Buena pregunta. podemos hacerlo de dos formas:
  • Si vamos a utilizar un plugin, podemos cambiar la configuración username/password por server. Siempre que ese plugin lo permita, por ejemplo tomcat7-maven-plugin lo permite.  
<plugin>
    <groupId>org.apache.tomcat.maven</groupId>
    <artifactId>tomcat7-maven-plugin</artifactId>
    <version>2.2</version>
    <configuration>
        <url>http:// localhost:8080/manager</url>
        <server>TomcatServerConfiguredInSettingsXml</server>
    </configuration>
</plugin>
<build>
    <extensions>
        <extension>
            <groupId>com.github.shyiko.servers-maven-extension</groupId>
            <artifactId>servers-maven-extension</artifactId>
            <version>1.3.1</version>
        </extension>
    </extensions>
</build>
<profiles>
    <profile>
        <id>local</id>
        <properties>
            <mysql.userName>${settings.servers.mysql-local.username}</mysql.userName>
            <mysql.password>${settings.servers.mysql-local.password}</mysql.password>
        </properties>
    </profile>
</profiles>

martes, 10 de septiembre de 2019

Como encriptar contraseñas en WSO2 con Cipher tool y Secure Vault

Hoy vamos a hablar de como configurar y utilizar Cipher Tool y Secure Vault en un producto de WSO2. Con estas herramientas podremos encriptar y utilizar claves sin necesidad de ponerlas a fuego en nuestro código. Además pensando en proyectos a desplegar en múltiples entornos, podremos referirnos a estas contraseñas a través de alias sin necesidad de cambiar el código por cada entorno. 

En este post no nos centraremos en como configurar o personalizar la herramienta, simplemente en como activarla y poder usarla manualmente.
  • Cipher tool
Si el uso que vamos a hacer de Cipher Tool es el de encriptar contraseñas. Podemos hacer las encriptaciones manualmente (tal y como veremos mas adelante) o a través del fichero cipher-text.properties. Asociandolas en dicho fichero a un alias. Ejemplo:

WSO2CarbonDB.password=admin

Independientemente de si hemos incluido o no alguna contraseña en el fichero cipher-text.properties, deberemos habilitar la herramienta de encriptación para poder trabajar con la misma.  Y esto lo conseguimos dirigiéndonos a la carpeta bin de nuestro producto y ejecutando el siguiente comando.

./ciphertool.sh -Dconfigure

La primera vez que lo ejecutemos nos pedirá la contraseña de nuestro contenedor de claves. Recordemos que la contraseña por defecto es wso2carbon. Y ademas encriptará las contraseñas que tengamos en el fichero cipher-text.properties.

 Si queremos utilizar estas contraseñas en los ficheros de configuración deberemos cambiar donde antes estaba el valor de la contraseñas por el alias que hemos creado. Ejemplo del fichero master-datasources.xml.

<url>jdbc:h2:./repository/database/WSO2CARBON_DB</url>
<username>wso2carbon</username>
<password>secretAlias:WSO2CarbonDB.password</password>
<driverClassName>org.h2.Driver</driverClassName>

Una vez configurada la herramienta podemos volver a ejecutarla para que nos encripte otras contraseñas. De forma individual y sin necesidad de utilizar el fichero cipher-text.properties. Para ello debemos ejecutar el comando ciphertool, el cual tras pedirnos una contraseña, nos devolverá el valor de la misma, ya encriptada.
  • Secure Vault
Ahora veremos como podemos usar Secure Vault para generar contraseñas a través de la consola de administración de WSO2 y como utilizarlas en nuestras integraciones. El primer paso sera arrancar nuestro producto WSO2, teniendo en cuenta que tras haber habilitado antes cipher tool, ahora se nos requerirá la contraseña del contenedor de claves cada vez que lo arranquemos.

Una vez arrancado podemos seguir creando alias/contraseñas a traves de la opción de menu 'Manage -> Secure Vault Tool > Add new password to encrypt and store'. Estas contraseñas se almacenaran en el registry.

Estos nuevos alias generados podrán ser utilizado tanto en el código de nuestras integraciones como en los ficheros de configuración de synapse. De la siguiente forma:
  • En un template, sequence, api o proxy podríamos obtener el valor asociado a un alias de la siguiente forma:
<property name="password" expression="wso2:vault-lookup('alias.to.use')"/>
  • En un fichero de configuracion lo podriamos utilizar asi:
{wso2:vault-lookup('alias.to.use')}

Y para terminar un ultimo truco. Es posible que al intentar crear una nueva contraseña nos diga que no es segura y que no permite almacenarla. Si queremos cambiar la expresión regular que determina la validación de las contraseñas del Secure Vault, debemos modificar la propiedad org.wso2.SecureVaultPasswordRegEx del fichero carbon.properties.

domingo, 8 de mayo de 2016

Codificar y Decodificar con AES. Parte II: Como codificar y que te funciones contra Salesforce

En el ejemplo anterior, vimos como hacer una encriptación con AES de forma sencilla. Este ejemplo es un poco más complejo. Y además nos permitirá des/encriptar de tal forma que podamos tener una comunicación fluida con las librerías de Salesforce (Apex).

Pero para empezar, vamos profundizar un poco más sobre conceptos de la encriptación:
  • ¿Que es CBC? Es un 'modo de operación' que permite encriptar el conjunto de bloques (los cifrados por AES) entre sí. Más info aquí.
  • ¿Que es IV? Es un vector de inicialización requerido por el modo de operación. Una secuencia unica binaria usada en las operaciones de encriptación. Más info aquí.
La clave en la comunicación con Salesforce, se centra en dos aspectos importantes:
  • El vector de inicialización es parte del texto codificado. El comienzo para ser más concreto.
  • Después de encriptar el texto hay que codificar la respuesta en Base64. Y antes de desencriptarlo hay que decodificar el texto a tratar en Base64 .
Ejemplo de encriptación. El método 'cipherData' ya se indica en el post anterior:

byte[] aEncriptarBytes = cadenaAEncriptar.getBytes();
//generamos un vector de iniciación de 128 bits aleatorio
byte[] iv = new byte[128];
new Random().nextBytes(iv);
//concateno vector de iniciacion mas el texto a encriptar en bytes
byte[] cadenaFinal = new byte[iv.length + aEncriptarBytes.length];
System.arraycopy(iv, 0, cadenaFinal, 0, iv.length);
System.arraycopy(aEncriptarBytes, 0, cadenaFinal, iv.length, aEncriptarBytes.length);
//Creo los objetos que permiten la encriptacion
PaddedBufferedBlockCipher aes = new PaddedBufferedBlockCipher(new CBCBlockCipher(new AESEngine()));
CipherParameters ivAndKey = new ParametersWithIV(new KeyParameter(llave.getBytes()), iv);
aes.init(true, ivAndKey);
//encriptamos el conjunto total de bytes (vector y texto). 
byte[] result = cipherData(aes, cadenaFinal);
//codifico el resultado a base64
byte[] bEncriptados = Base64.encode(cadenaFinal);
String textoEncriptado = new String(encodeObuf);

Ejemplo de desencriptación:

byte[] llaveBytes = llave.getBytes();
byte[] bDesencriptados = null;
// decodificamos el texto a desencriptar
byte[] encryptedTextBytes = Base64.decode(textoEncriptado);
// Descomponemos el texto encriptado. La primera parte incluye el vector de iniciacion
byte[] iv = Arrays.copyOfRange(encryptedTextBytes, 0, 128);
// Obtenemos el texto exacto a desencriptar
byte[] validBytes = Arrays.copyOfRange(encryptedTextBytes, 128, encryptedTextBytes.length);
//Creamos objeto que permite la desencriptacion
PaddedBufferedBlockCipher decryptCipher = new PaddedBufferedBlockCipher(new CBCBlockCipher(new AESEngine()));
ParametersWithIV parameterIV = new ParametersWithIV(new KeyParameter(llaveBytes), iv);
decryptCipher.init(false, parameterIV);
//Procedemos a desencriptar
int bProcesados = decryptCipher.processBytes(validBytes, 0, validBytes.length, bDesencriptados, 0);
decryptCipher.doFinal(bDesencriptados, bProcesados);
textoDesencriptado = new String(bProcesados);

sábado, 23 de abril de 2016

Codificar y Decodificar con AES. Parte I: Ejemplo básico

Esta semana he estado peleándome con la encriptación AES. Así que que mejor, después de solucionarlo, que indicar como poder realizar dicha encriptación.

Debemos tener en cuenta que para hacer esta encriptación, podemos usar clases propias de la JDK o alguna librería de utilidad. Nosotros vamos a usar la librería 'bouncy castle' (artifactId: bcprov-jdk16 y versión: 1.46).

Pero para empezar debemos tener unos cuantos conceptos claros:
  • ¿Que es AES? Un algoritmo de cifrado de datos en bloques (tan grandes como el tamaño de su contraseña, que es como mínimo de 128 bits). El estándar desde comienzos del siglo.Más info aquí.
  • Llave: Para poder encriptar y desencriptar, el algoritmo necesita una llave (o contraseña) conocida por los sistema a interactuar. Esta llave debe tener el mismo tamaño que los bloques del cifrado. 
El  funcionamiento a la hora de des/encriptar es exactamente igual, lo único que varía es la forma de crear el objeto que nos permite la des/encriptación. Si queremos que encripte pasaremos como parámetro de entrada 'true' y si queremos que desencripte, pasaremos 'false'.

boolean modoEncriptacion = true; // true encriptar:, false: desencriptar
byte[] llaveBytes = llave.getBytes(); // 'llave' es la contraseña para realizar la encriptacion
PaddedBufferedBlockCipher cipher = new PaddedBufferedBlockCipher(new AESEngine());
cipher.init(modoEncriptacion, new KeyParameter(llaveBytes));

La des/encriptación funciona con array de bytes, por tanto tanto la contraseña como el texto a des/encriptar debemos pasarlo a un array de bytes. La lógica es bastante sencilla:
  • Debemos crear un buffer de salida cuyo tamaño nos lo puede decir el propio 'cipher' con 'getOutputSize'.
  • Copiar los datos des/encriptado del array de bytes a des/encriptar hacía el de salida. Indicando los bytes a copiar (lo normal es de 0 al máximo de tamaño del buffer de salida)
  • Procesar los bytes finales que se han podido quedar sin copiar en el buffer de salida. Importante: Indicar a partir de que punto debe seguir obteniendo datos (a partir del byte que el último byte que haya procesado el método anterior).

private static byte[] cipherData(final PaddedBufferedBlockCipher cipher, final byte[] data) throws Exception {
 int minSize = cipher.getOutputSize(data.length);
 byte[] outBuf = new byte[minSize];
 int bytesProcesados1 = cipher.processBytes(data, 0, data.length, outBuf, 0);
 int bytesProcesados2 = cipher.doFinal(outBuf, bytesProcesados1);
 int tamanyoTotal = bytesProcesados1 + bytesProcesados2;
 byte[] resultado = new byte[tamanyoTotal];
 System.arraycopy(outBuf, 0, resultado, 0, tamanyoTotal);
 return result;
}

Ejemplo completo de des/encriptación:

PaddedBufferedBlockCipher encryptCipher = new PaddedBufferedBlockCipher(new AESEngine());
encryptCipher.init(true, new KeyParameter(llaveBytes));
byte[] result = cipherData(encryptCipher, aEncriptarBytes);
PaddedBufferedBlockCipher decryptCipher = new PaddedBufferedBlockCipher(new AESEngine());
decryptCipher.init(false, new KeyParameter(llaveBytes));
byte[] encodedBytes = Base64.decode(encoded.getBytes());
result = cipherData(decryptCipher, encodedBytes);