Como pudimos ver en el anterior post sobre encriptación sobre 2005/2008 encriptar nuestra información sensible no es trivial. Analizando el funcionamiento a fondo de los mecanismos de encriptación y de la implementación en SQL Server se determinó que no es suficiente con habilitar la encriptación sobre nuestros datos. Debemos por tanto comprender a fondo la implementación para evitar dejar datos en claro de forma involuntaria. Con SQL Server 2008 aparece la encriptación transparente (TDE) que afecta a la base de datos completa y es transparente para las aplicaciones su uso lo cual mejora su usabilidad en aplicaciones de terceros o que no puedan ser modificadas.

En este post vamos a analizar la encriptación TDE y finalmente daremos un conjunto de recomendaciones para aquellos que requieran encriptar información puedan hacerlo de una forma segura. Crearemos una base de datos para las pruebas así como una tabla que contendrá nuestra información a encriptar:

USE MASTER

CREATE DATABASE ENCRYPTION

GO

USE ENCRYPTION

GO

CREATE TABLE DATA

(

    ID INT IDENTITY (1,1) PRIMARY KEY,

    NOMBRE VARCHAR(255) NOT NULL,

    PASSWORD VARCHAR(255) NOT NULL

)

GO

 

Al igual que en el caso de la encriptación no transparente, los pasos para establecer la base de la jerarquía de encriptación son necesarios. Deberemos crear la master key y crear un certificado protegido por dicha master key. A continuación crearemos una database key protegida por el certificado que hemos creado previamente.

USE MASTER

CREATE MASTER KEY ENCRYPTION BY PASSWORD = ‘Pa$$w0rd’

GO

CREATE CERTIFICATE CertificadoTDE WITH SUBJECT = ‘Certificado para TDE’

GO

CREATE SYMMETRIC KEY ClaveSimetricaTDE

WITH ALGORITHM = AES_256

ENCRYPTION BY CERTIFICATE CertificadoTDE

GO

USE ENCRYPTION

CREATE DATABASE ENCRYPTION KEY

WITH ALGORITHM = AES_256

ENCRYPTION BY SERVER CERTIFICATE CertificadoTDE;

GO

Una vez tenemos la infraestructura lista para encriptar lo primero que debemos hacer es hacer un respaldo del certificado y del password utilizado para la master key. Nunca se hace suficiente hincapié en este aspecto pero hay algo que debéis tener siempre presente: el certificado y la clave privada de éste son tan valiosos como la propia información que encriptemos. Sin un backup de estos elementos no será posible recuperar los datos de ninguna forma con lo cual perderemos el acceso a la información. Tanto para encriptación no transparente como para encriptación transparente recomendamos, antes de encriptar nada, realizar las siguientes acciones:

  • Backup de la service key.
  • Backup de la master key.
  • Backup del certificado con la clave privada.

Esto en T-SQL quedaría traducido a lo siguiente:

USE [master]

GO

BACKUP SERVICE MASTER KEY TO FILE = ‘C:ServiceKey.key’

ENCRYPTION BY PASSWORD = ‘Pa$$w0rd’;

GO

BACKUP MASTER KEY TO FILE = ‘C:MasterKey.key’

ENCRYPTION BY PASSWORD = ‘Pa$$w0rd’;

GO

BACKUP CERTIFICATE CertificadoTDE

TO FILE = ‘C:CertificadoTDE.cer’

WITH PRIVATE KEY (

FILE = ‘C:CertificadoTDE.key’,

ENCRYPTION BY PASSWORD = ‘Pa$$w0rd’

);

GO

 

El guardar dichos datos en C: se ha realizado únicamente como ejemplo siendo necesario el almacenarlos offsite en realidad. Preferiblemente realizaremos el backup directamente off-site a través de una ruta UNC a un servidor externo al que estemos conectados mediante una VPN. En su defecto se podría almacenar en un dispositivo externo local (tipo pendrive) del cual mantendremos al menos 2 copias off-site separadas geográficamente. Por supuesto los passwords utilizados para encriptar cada uno de estos elementos deberá ser almacenado de forma segura y evitando utilizar passwords débiles como fechas, palabras de diccionario, etc.

Una vez tenemos respaldados estos elementos procederemos a insertar algunos datos en nuestra tabla, activaremos TDE y comprobaremos que seguimos teniendo acceso a dichos datos de forma transparente:

 

INSERT INTO DATA

VALUES (‘USUARIO 1’,‘11111111’)

GO

INSERT INTO DATA

VALUES (‘USUARIO 2’,‘22222222’)

GO

INSERT INTO DATA

VALUES (‘USUARIO 3’,‘33333333’)

GO

SELECT * FROM DATA

 

 

Activamos la encriptación:

ALTER DATABASE encryption

SET ENCRYPTION ON;

GO

Una vez hecho esto, podemos comprobar el estado actual de la encriptación:

select encryption_state, percent_complete FROM sys.dm_database_encryption_keys

where database_id=DB_ID(‘encryption’)

 

Básicamente cuando activamos la encriptación el estado pasará a 2 (encriptación en proceso) y quedará con el valor de 3 cuando finalice. El valor de la columna percent_complete nos indicará el % de la operación en curso y quedará en 0 una vez finalizada. Esto es importante en bases de datos grandes que implicarán un tiempo considerable el ser completamente encriptadas/desencriptadas.

Por tanto llegados a este punto, deberíamos estar relativamente seguros de que no existe información desencriptada en nuestros ficheros de base de datos. Como medida de seguridad adicional, el habilitar TDE fuerza a rellenar con 0s la parte pendiente del VLF (Virtual Log File) en uso para forzar el uso de un nuevo VLF encriptado. Esto nos garantiza que no quedará texto en claro en el log de transacciones una vez la base de datos se habilite para encriptación transparente. Ahora bien, ¿qué ocurre con la parte de los logs ya utilizada previamente? 🙂

Vamos a echar una ojeada al log cuando insertamos una nueva fila:

INSERT INTO DATA

VALUES (‘USUARIO 4’,‘44444444’)

GO

DBCC LOG(encryption,4)

 

En el campo Log Record tenemos almacenado el contenido del registro del log en binario. Utilizaremos el mismo script que utilizamos en el post anterior sobre encriptación no transparente:

DECLARE @cadena VARCHAR(MAX)

SET @cadena = ‘0x00003E00290000005300000002000200B40300000000020299000000010000001B00000029000000530000001100000100000D00000000010000000000000300220000001A003442300008000100000003000002001A0022005553554152494F20343434343434343434730F0101000C0000E7A4787D0000010200040204000A0100864707664657’

DECLARE @bin VARBINARY(MAX)

DECLARE @sql NVARCHAR(MAX)

SET @sql = ‘SELECT @bin = ‘ + replace(@cadena,’00’,’20’)

EXEC sp_executesql @sql, N’@bin VARBINARY(MAX) OUTPUT’,@bin OUTPUT

SELECT convert(varchar(max),@bin)

Vemos por tanto que la «desencriptación» transparente se realiza también a nivel de logrecords cuando utilizamos DBCC LOG. Ahora nos queda analizar que ocurre realmente con los ficheros físicos del log y de la base de datos. Para ello abriremos el fichero de log con un editor hexadecimal y buscaremos por ejemplo el registro de insertar el usuario 11111111:

Por tanto, la encriptación transparente únicamente nos protege el log a partir del momento que la activamos, quedando el resto de registros en claro. Es necesario por tanto conseguir que todo el log se reutilice una vez activada la encriptación. Esto debido al funcionamiento circular de los VLF complica el proceso en cierta forma pues deberíamos realizar un checkpoint, un backup del log, una reducción del tamaño del log y luego devolver el log a su tamaño inicial. Por tanto, teniendo en cuenta tanto la encriptación transparente como la no transparente desde el punto de vista de seguridad recomendamos enérgicamente la creación de una nueva base de datos vacía donde, una vez configurado el método de encriptación a utilizar, volquemos toda la información de nuestra base de datos actual. De esta forma evitamos dejar páginas con datos desencriptados (en el caso de encriptación no TDE) como restos en el log de transacciones (ambas encriptaciones). Por tanto la estrategia segura a seguir sería:

  1. Crear la nueva base de datos donde encriptaremos la información.
  2. Configurar la jerarquía de encriptación necesaria (claves, certificados, etc.) y activar TDE si vamos a utilizarla en SQL Server 2008.
  3. Transferir los objetos de la base de datos original a la nueva base de datos. En el caso de TDE no necesitamos tomar ninguna medida adicional para la copia. En el caso de encriptación no TDE deberemos asegurarnos de transferir las tablas sin datos en claro, esto es, utilizando la función de encriptación sobre las columnas necesarias para que se escriban ya encriptadas.
  4. Eliminamos la base de datos original (DROP DATABASE)
  5. Limpiaremos el buffer pool (DBCC DROPCLEANBUFFERS)
  6. Eliminaremos de forma segura los ficheros de datos y de log de la base de datos original. Para realizar un borrado seguro deberemos utilizar una herramienta específica de borrado seguro que nos sobreescriba el fichero con patrones aleatorios antes de borrarlo a nivel de sistema de ficheros. De esta forma evitaremos que queden rastros desencriptados en nuestro disco duro.

En conclusión hemos visto que encriptar información tampoco es una labor trivial con TDE si queremos hacerlo bien. Recomendamos a todos aquellos que sean responsables de bases de datos donde el cifrado sea vital y que pueda tener consecuencias graves legales o de seguridad que planteen un plan de encriptación serio y que contemple todos los escenarios posibles de ataque. Nunca debemos olvidar que siempre existe un eslabón más débil en la cadena de seguridad. Por ejemplo por defecto el protocolo TDS no utiliza encriptación con lo que todos nuestros esfuerzos a nivel de base de datos se volatilizan tan pronto como salen los paquetes por la red. Aun utilizando SSL, las aplicaciones que hagan uso de los datos privados deben ser auditadas para asegurar que no dejan rastros en forma de ficheros temporales, caché, etc. en los clientes al ser utilizadas. La seguridad es una problemática que alcanza a todos los niveles, incluidos los usuarios y sus passwords o dispositivos biométricos asociados. Por ejemplo, la mayoría de los lectores biométricos incluidos en los portátiles pueden ser engañados con facilidad creando una huella falsa a partir de una huella del usuario real.

 

Rubén Garrigós