Ir al contenido principal

Cifrado y descifrado de datos en MySQL con AES y SHA

Cifrado y descifrado de datos en MySQL con AES y SHA

La protección de la información es un tema importante, y toma más relevancia cuando esta información se encuentra almacenada en la nube y es accesible desde Internet.

Una forma practica y eficiente de cifrar los datos para su almacenamiento en una base de datos y su posterior descifrado para tener acceso a los mismos es el uso de Advanced Encryption Standard (AES), que es un entandar de cifrado aprobado por la la Agencia de Seguridad Nacional de los Estados Unidos (NSA) para el cifrado de información no clasificada en 2005.


Este cifrado utiliza una Llave “KEY” para el cifrado, de tal forma que si no se conoce esta Llave no se podrá recuperar los datos originales.

Además para hacer más segura esta Llave se puede utilizar el Secure Hash Algorithm (SHA), lo que permitirá generar una llave HASH más segura que la cadena original.

Nota: AES_ENCRYPT() y AES_DECRYPT() fueron añadidas en la versión 4.0.2, y pueden considerarse como las funciones de cifrado y descifrado más seguras disponibles actualmente en MySQL.

NOTA: al cifrar los datos estos deben tener el tamaño suficiente para almacenar el valor y el cifrado, una forma fácil de calcular el tamaño del campo es usar alguna hoja de cálculo y usar la siguiente formula, donde longitud_de_la_cadena es el tamaño máximo del campo.

 16 * (trunc(longitud_de_la_cadena / 16) + 1)

Ejemplo si el teléfono va a tener 10 números la formula sería así

 16 * (trunc(10 / 16) + 1)

Y el resultado es 16, que sería el tamaño del campo para guardar un número telefónico de 10 dígitos.


1. Para entender y aplicar estos conceptos se crea la siguiente base de datos de prueba.

CREATE DATABASE base_cifrada DEFAULT CHARACTER SET latin1 COLLATE latin1_spanish_ci;

USE base_Cifrada;

CREATE TABLE tabla_cifrada(
id INT(11) NOT NULL PRIMARY KEY AUTO_INCREMENT,
nombre VARCHAR(50),
telefono VARCHAR(16)
)ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=latin1  COLLATE latin1_spanish_ci;

Nota: Como se puede ver la base de datos no tiene nada de especial, el proceso de cifrado y descifrado se realizará al insertar y seleccionar los datos.

2.- Ahora se insertaran los registros, y cada campo que se desee cifrar se hará utilizando el comando AES_ENCRYPT, que recibe como parámetros el valor a cifrar y la llave, en este caso para la llave se utiliza el comando SHA2 que recibe como parámetro la llave que se utilizara y el número de bits del HASH, de esta forma el valor será cifrado y se almacenará en la base de datos.

INSERT INTO tabla_cifrada(
nombre, 
telefono
VALUES (
AES_ENCRYPT('María', SHA2('CLAVE',512)),
AES_ENCRYPT('7757512345', SHA2('CLAVE',512))
);
INSERT INTO tabla_cifrada(
nombre,
telefono
VALUES (
AES_ENCRYPT('José', SHA2('CLAVE',512)),
AES_ENCRYPT('7757523456', SHA2('CLAVE',512))
);

3.- Al consultar los registros almacenados se con la consulta SELECT * FROM tabla_cifrada; el resultado se ve como en la imagen siguiente.



4.- Para poder ver los valores originales se utiliza el comando CONVERT, con los siguientes parámetros:
a) El comando AES_DECRYPT, que se encarga de descifrar el valor almacenado, para esto necesita como parámetros el campo y la llave.
b) Como la llave se generó con SHA2 hay que volverlo a generar para poder tener la llave con la que se cifro el valor.
c) Con el comando USING UTF8 se convierte el valor binario a texto.
d) Utilizando AS se nombra el campo generado con el nombre que se desee, en este caso el mismo nombre del campo donde se guardo el valor.

SELECT 
id,
CONVERT(AES_DECRYPT(nombre, SHA2('CLAVE',512)) USING utf8) AS nombre, 
CONVERT(AES_DECRYPT(telefono, SHA2('CLAVE',512)) USING utf8) AS telefono 
FROM 
tabla_cifrada;

En la siguiente imagen se puede ver el procedimiento y el resultado, este paso se realiza por cada campo que se quiera descifrar.



Segunda forma

1.- Otra forma cifrar los datos si no se desea utilizar un HASH para la llave, se puede utilizar directamente como parámetro un valor Alfanumérico, tal como se muestra en el siguiente código. 

INSERT INTO tabla_cifrada(
nombre,
telefono
VALUES (
AES_ENCRYPT('Maria', 'CLAVE'), 
AES_ENCRYPT('7757512345', 'CLAVE')
);


2.- En la siguiente imagen se puede ver el resultado al hacer la consulta de los datos con SELECT * FROM tabla_cifrada;



3.- para descifrar el valor se utiliza AES_DECRYPT con el nombre del campo y la llave Alfanumérica.

SELECT 
id,
CONVERT(AES_DECRYPT(nombre,'CLAVE') USING utf8) AS nombre, 
CONVERT(AES_DECRYPT(telefono,'CLAVE') USING utf8) AS telefono 
FROM 
tabla_cifrada;

4.- En la siguiente imagen se muestra el resultado de seleccionar los datos convirtiéndolos previamente.



NOTAS

Una forma de no estar creando el HASH cada vez que se quiera cifrar o descifrar es crear una variable y posteriormente solo llamarla cuando sea necesario, tal como se muestra en el siguiente ejemplo.

SET @clave:=SHA2('CLAVE',512);

INSERT INTO table VALUES (1,AES_ENCRYPT('text',@clave));



Comentarios

Entradas más populares de este blog

Creación de Librerías en Java

Creación de Librerías en Java   Las librerías son un conjunto de clases con funciones especificas que ayudan a desarrollar aplicaciones más complejas de una forma sencilla, por ejemplo si se requiere realizar cálculos matemáticos y emplear el funciones como el Seno o Coseno, simplemente se importa la librería Math y se utilizan estos métodos, en lugar de desarrollarlos. Java cuenta con una extensa lista de librerías disponibles dentro del JDK o desarrolladas por terceros, pero también existe la posibilidad de desarrollar librerías propias para reutilizar de forma más eficiente el código, por ejemplo si se trabaja de forma cotidiana con conexión a base de datos, se pueden desarrollar métodos genéricos que realicen la conexión, que validen las consultas, etc. de forma que su uso reduzca el tiempo de desarrollo e incremente la productividad. Para este tutorial se van a crear dos proyectos en NetBeans, uno sera la librería y el otro proyecto hará uso de esta.

Elegir la clase a ejecutar en NetBeans, MVC

Elegir la clase a ejecutar en NetBeans Para que java pueda ejecutar una aplicación esta debe tener un método conocido como punto de entrada, este método tiene la sintaxis: void static void main(String [] sax){ //código } En ocasiones en una aplicación tiene varios puntos de entrada, que pueden servir para probar diferentes partes de la aplicación sin tener que recorrer o pasar por varias clases, para esto se puede seleccionar directamente en las propiedades del proyecto que clase será la principal.

Librerías JOptionPane para generar ventanas de entrada y salida de datos

Para poder introducir datos leídos desde el teclado existen varias formas, una de ellas hace uso de la librería javax.swing.JOptionPane que entre otras opciones permite mostrar ventanas para introducir datos, y ventanas para mostrar valores. Con el uso de esta librería se crean pequeñas interfaces definidas por el sistema, pero ya se hace uso de las librerías graficas swing, que se verán más adelante.