Este artículo brinda una comprensión de alto nivel del enmascaramiento dinámico de datos en SQL Server junto con sus casos de uso, mejores prácticas e implicaciones de seguridad para usuarios avanzados de SQL (incluidos desarrolladores y evaluadores). Además, los lectores de este artículo se familiarizarán con la aplicación de diferentes tipos de enmascaramiento dinámico de datos. El artículo también destaca la importancia del uso de nivel avanzado del enmascaramiento de datos en las tareas diarias de desarrollo y prueba de bases de datos.
Requisitos previos
Primero repasemos los requisitos previos para este artículo.
Familiaridad con T-SQL
Este artículo asume que los lectores están bien familiarizados con los scripts T-SQL y pueden escribir y ejecutar cómodamente consultas SQL para ver y manipular las bases de datos SQL.
Conceptos básicos del enmascaramiento dinámico de datos
Este artículo también asume que los lectores conocen los conceptos básicos del enmascaramiento dinámico de datos en SQL Server. Consulte el artículo Enmascaramiento de datos en SQL Server para principiantes para familiarizarse con los conceptos básicos del enmascaramiento dinámico de datos si aún no lo ha hecho.
Base de datos Azure SQL o compatibilidad con SQL Server 2016
La función de enmascaramiento de datos dinámicos está disponible en SQL Server 2016 a SQL Server 2019, por lo que se recomienda tener uno de los siguientes:
1. Base de datos Azure SQL
2. SQL Server 2016 instalado de forma local o remota.
Configuración de la base de datos de muestra
Recuerde crear una base de datos de muestra con el siguiente script T-SQL compatible con SQL Server 2016 o como Azure SQL Database si desea seguir el tutorial de este artículo:
-- Create sample database ITSalesV2 CREATE DATABASE ITSalesV2; GO USE [ITSalesV2] -- (2) Create MonthlySale table CREATE TABLE [dbo].[MonthlySale]( [SaleId] [int] IDENTITY(1,1) NOT NULL PRIMARY KEY, [SellingDate] [datetime2](7) NULL, [Customer] [varchar](50) NULL, [Email] [varchar] (200) NULL, [Product] [varchar](150) NULL, [TotalPrice] [decimal](10, 2) NULL, ) -- (2) Populate monthly sale table SET IDENTITY_INSERT [dbo].[MonthlySale] ON INSERT INTO [dbo].[MonthlySale] ([SaleId], [SellingDate], [Customer],[Email], [Product], [TotalPrice]) VALUES (1, N'2019-05-01 00:00:00', N'Asif', N'[email protected]', N'Dell Laptop', CAST(300.00 AS Decimal(10, 2))) INSERT INTO [dbo].[MonthlySale] ([SaleId], [SellingDate], [Customer],[Email], [Product], [TotalPrice]) VALUES (2, N'2019-05-02 00:00:00', N'Mike',N'[email protected]', N'Dell Laptop', CAST(300.00 AS Decimal(10, 2))) INSERT INTO [dbo].[MonthlySale] ([SaleId], [SellingDate], [Customer],[Email], [Product], [TotalPrice]) VALUES (3, N'2019-05-02 00:00:00', N'Adil',N'[email protected]',N'Lenovo Laptop', CAST(350.00 AS Decimal(10, 2))) INSERT INTO [dbo].[MonthlySale] ([SaleId], [SellingDate], [Customer],[Email], [Product], [TotalPrice]) VALUES (4, N'2019-05-03 00:00:00', N'Sarah',N'[email protected]', N'HP Laptop', CAST(250.00 AS Decimal(10, 2))) INSERT INTO [dbo].[MonthlySale] ([SaleId], [SellingDate], [Customer],[Email], [Product], [TotalPrice]) VALUES (5, N'2019-05-05 00:00:00', N'Asif', N'[email protected]', N'Dell Desktop', CAST(200.00 AS Decimal(10, 2))) INSERT INTO [dbo].[MonthlySale] ([SaleId], [SellingDate], [Customer],[Email], [Product], [TotalPrice]) VALUES (6, N'2019-05-10 00:00:00', N'Sam',N'[email protected]', N'HP Desktop', CAST(300.00 AS Decimal(10, 2))) INSERT INTO [dbo].[MonthlySale] ([SaleId], [SellingDate], [Customer],[Email], [Product], [TotalPrice]) VALUES (7, N'2019-05-12 00:00:00', N'Mike',N'[email protected]', N'iPad', CAST(250.00 AS Decimal(10, 2))) INSERT INTO [dbo].[MonthlySale] ([SaleId], [SellingDate], [Customer],[Email], [Product], [TotalPrice]) VALUES (8, N'2019-05-13 00:00:00', N'Mike',N'[email protected]', N'iPad', CAST(250.00 AS Decimal(10, 2))) INSERT INTO [dbo].[MonthlySale] ([SaleId], [SellingDate], [Customer],[Email], [Product], [TotalPrice]) VALUES (9, N'2019-05-20 00:00:00', N'Peter',N'[email protected]', N'Dell Laptop', CAST(350.00 AS Decimal(10, 2))) INSERT INTO [dbo].[MonthlySale] ([SaleId], [SellingDate], [Customer],[Email], [Product], [TotalPrice]) VALUES (10, N'2019-05-25 00:00:00', N'Peter',N'[email protected]', N'Asus Laptop', CAST(400.00 AS Decimal(10, 2))) SET IDENTITY_INSERT [dbo].[MonthlySale] OFF
Comprobación de datos
Verifique la base de datos de ejemplo recién creada y poblada ITSalesV2 ejecutando el siguiente script:
-- View monthly sales data SELECT s.SaleId ,s.SellingDate ,s.Customer ,s.Email ,s.Product ,s.TotalPrice FROM dbo.MonthlySale s
La salida es la siguiente:
Crear un usuario sin privilegios
Cree un usuario sin privilegios sin inicio de sesión que solo tenga permiso SELECT en la tabla MonthlySale que verá los datos enmascarados como requisito previo para este artículo. Utilice el siguiente script para hacerlo:
-- Create DataUser to have Select access to MonthlySale table CREATE USER DataUser WITHOUT LOGIN; GRANT SELECT ON MonthlySale TO DataUser;
Creación de un procedimiento para comprobar el estado de enmascaramiento
Este artículo también asume que hay un procedimiento almacenado en la base de datos de muestra que nos muestra el estado de enmascaramiento de datos dinámicos de las columnas en las tablas de la base de datos:
-- Stored procedure to check dynamic data masking status CREATE PROC ShowMaskingStatus AS BEGIN SET NOCOUNT ON SELECT c.name, tbl.name as table_name, c.is_masked, c.masking_function FROM sys.masked_columns AS c JOIN sys.tables AS tbl ON c.[object_id] = tbl.[object_id] WHERE is_masked = 1; END
Tipos de enmascaramiento de datos dinámicos
Hay cuatro tipos comunes de enmascaramiento de datos dinámicos en SQL Server:
1. Máscara(s) de datos predeterminada(s)
2. Máscara(s) de datos parcial(es)
3. Máscara(s) de datos aleatorios
4. Máscara(s) de datos de cadena personalizada(s)
Ahora vamos a implementar los cuatro tipos comunes de enmascaramiento dinámico de datos.
Implementación del enmascaramiento de datos predeterminado
El enmascaramiento de datos predeterminado oculta una columna por completo de un usuario no autorizado cubriendo todos los valores de la columna con un carácter especial que hace que sea muy difícil adivinar el contenido de la columna.
Requisito comercial
Ahora suponga que recibe un requisito comercial que establece que las direcciones de correo electrónico de los clientes deben estar completamente ocultas (enmascaradas) debido a la confidencialidad de esta información.
La mejor manera de cumplir con este requisito comercial es enmascarar la columna Correo electrónico. utilizando el enmascaramiento dinámico de datos (DDM).
Enmascaramiento de datos predeterminado de la dirección de correo electrónico
Vamos a modificar la tabla para enmascarar las direcciones de correo electrónico de la siguiente manera:
--Default dynamic data masking of Email column ALTER TABLE MonthlySale ALTER COLUMN Email varchar(200) MASKED WITH (FUNCTION = 'default()');
Comprobación del estado de enmascaramiento
Verifique el estado de enmascaramiento de datos dinámicos utilizando el siguiente procedimiento almacenado basado en un script T-SQL al que se hace referencia en la documentación de Microsoft:
-- Checking dynamic data masking status EXEC ShowMaskingStatus
El resultado nos muestra qué columnas se han enmascarado con éxito:
Ver columna de correo electrónico como usuario de datos
A continuación, ejecute la declaración Select para ver las ventas mensuales (tabla) como un usuario con privilegios bajos llamado DataUser que solo tiene permiso de selección en la tabla de la siguiente manera:
-- Execute SELECT as DataUser EXECUTE AS USER = 'DataUser'; -- View monthly sales SELECT s.SaleId,s.SellingDate,s.Customer,s.Email,s.Product,s.Product from dbo.MonthlySale s -- Revert the User back to what user it was before REVERT;
La salida es la siguiente:
Implementación del enmascaramiento parcial de datos
El enmascaramiento parcial de datos, como su nombre lo indica, oculta parcialmente una columna para que no la vea un usuario no autorizado que cubre una parte de los valores de la columna con caracteres especiales, lo que hace que el contenido de la columna sea algo legible pero aún así difícil de adivinar.
Requisito comercial
Ahora piense en un requisito comercial en el que se le ha pedido que oculte parcialmente el nombre de los clientes de tal manera que solo el primer carácter del nombre permanezca visible. La mejor manera de cumplir con este requisito empresarial es enmascarar la columna Cliente mediante el enmascaramiento de datos dinámicos parciales.
Enmascaramiento parcial de datos de nombres de clientes
Vamos a modificar la tabla para enmascarar parcialmente la columna Cliente de la siguiente manera:
-- Partial data masking of Customer names ALTER TABLE MonthlySale ALTER COLUMN [Customer] ADD MASKED WITH (FUNCTION = 'partial(1,"XXXXXXX",0)')
Comprobación del estado de enmascaramiento
Compruebe el estado de enmascaramiento de datos dinámicos:
-- Checking dynamic data masking status EXEC ShowMaskingStatus
El resultado nos muestra qué columnas se han enmascarado con éxito:
Ver la columna del cliente como un usuario de datos
Ver la tabla como un usuario de prueba Usuario de datos que debe ver los datos enmascarados:
-- Execute SELECT as DataUser EXECUTE AS USER = 'DataUser'; -- View monthly sales as DataUser SELECT s.SaleId,s.SellingDate,s.Customer,s.Email,s.Product,s.Product from dbo.MonthlySale s -- Revert the User back to what user it was before REVERT;
La salida es la siguiente:
Implementación de enmascaramiento de datos aleatorios
El enmascaramiento de datos aleatorios oculta una columna al azar de un usuario no autorizado al cubrir una columna en función de un rango de valores, lo que hace que sea muy difícil adivinar el contenido de la columna. Recuerde que el tipo de enmascaramiento de datos aleatorios solo se aplica a las columnas que almacenan solo números y se puede especificar proporcionando un rango para la aleatorización.
Requisito comercial
Recibe un requisito comercial que establece que el precio del producto debe enmascararse con un rango aleatorio de números para que los usuarios con privilegios bajos no puedan conocer los precios exactos del producto por motivos de privacidad. La mejor manera de cumplir con esta especificación comercial es enmascarar la columna PrecioTotal mediante el enmascaramiento de datos dinámicos aleatorios.
Enmascaramiento de datos aleatorios de la columna TotalPrice
Modifique la tabla MonthlySale para enmascarar TotalPrice aleatoriamente de la siguiente manera:
--Random dynamic data masking of TotalPrice column ALTER TABLE MonthlySale ALTER COLUMN [TotalPrice] decimal(10,2) MASKED WITH (FUNCTION = 'random(1, 12)')
Comprobación del estado de enmascaramiento
Verifique el estado de enmascaramiento de datos dinámicos ejecutando el siguiente procedimiento almacenado:
-- Checking dynamic data masking status EXEC ShowMaskingStatus
El resultado nos muestra qué columnas se han enmascarado correctamente:
Ver la columna PrecioTotal como usuario de datos
Ver la tabla como usuario de datos ahora:
-- Execute SELECT as DataUser EXECUTE AS USER = 'DataUser'; -- View monthly sales SELECT s.SaleId,s.SellingDate,s.Customer,s.Email,s.Product,s.TotalPrice from dbo.MonthlySale s -- Revert the User back to what user it was before REVERT;
La salida es la siguiente:
Recuerde que la salida puede diferir para la columna Datos aleatorios enmascarados debido a la generación de números aleatorios.
Implementación de enmascaramiento de datos de cadenas personalizadas
El enmascaramiento de datos de cadena personalizado, como su nombre lo indica, agrega un carácter personalizado para ocultar una columna, lo que hace que sea muy difícil adivinar su contenido. Recuerde que el enmascaramiento de datos de cadena personalizado se usa junto con el enmascaramiento de datos parcial al personalizar el carácter para enmascarar los valores reales de la columna. En otras palabras, el enmascaramiento de datos de cadenas personalizadas es una forma mejorada de enmascaramiento de datos parcial.
Requisito comercial
Considere un requisito comercial para mostrar solo el primer y último carácter de la columna Producto, mientras que el resto de los caracteres deben estar ocultos o enmascarados con guiones (-). La mejor manera de cumplir con esta especificación comercial es enmascarar la columna Producto mediante el enmascaramiento de datos dinámicos parciales con la cadena personalizada requerida.
Enmascaramiento de datos de cadenas de clientes de datos de ventas
Modifique la tabla MonthlySale para enmascarar la columna Producto de la siguiente manera:
--Custom string dynamic data masking of Product column ALTER TABLE MonthlySale ALTER COLUMN [Product] ADD MASKED WITH (FUNCTION = 'partial(1,"---",1)')
Comprobación del estado de enmascaramiento
Vale la pena verificar el estado de enmascaramiento de datos dinámicos en este punto usando el siguiente script:
-- Checking dynamic data masking status EXEC ShowMaskingStatus
El resultado muestra todas las columnas en las que se ha aplicado con éxito el enmascaramiento de datos dinámicos, como se muestra a continuación:
Ver la columna del producto como un usuario de datos
Ver la tabla como usuario de datos ahora:
-- Execute SELECT as DataUser EXECUTE AS USER = 'DataUser'; -- View monthly sales SELECT s.SaleId,s.SellingDate,s.Customer,s.Email,s.Product,s.TotalPrice from dbo.MonthlySale s -- Revert the User back to what user it was before REVERT;
La salida es la siguiente:
¡Felicidades! Ha implementado con éxito las cuatro técnicas de enmascaramiento.
Consulte el artículo Enmascaramiento de datos en SQL Server para principiantes para descartar los tipos de enmascaramiento de datos aplicados.
Mejores prácticas
Recuerde lo siguiente:
1. El enmascaramiento dinámico de datos no protege ni encripta los datos de la columna, por lo que no debe usarse para ese fin.
2. El usuario potencial que se supone que debe ver los datos enmascarados debe tener un acceso muy limitado para ver los datos y no debe recibir permiso de actualización para explotar los datos.
3. El usuario potencial, incluso con el permiso SELECCIONAR solamente, puede ejecutar consultas exhaustivas para adivinar el valor correcto, así que tenga cuidado con eso.
4. También puede usar ALTER COLUMN Email ADD MASKED WITH (FUNCTION ='email()') para enmascarar columnas de correo electrónico en lugar de usar el enmascaramiento dinámico predeterminado.
5. Puede usar el enmascaramiento de datos de cadenas personalizadas para ocultar un número de tarjeta de débito en un informe de transacciones al mostrar solo los últimos dos o cuatro dígitos, como podría haber visto en los recibos de compras.
Cosas que hacer
Ahora que puede implementar los cuatro tipos de enmascaramiento, intente lo siguiente para mejorar aún más sus habilidades:
1. Cree una base de datos de muestra siguiendo el tutorial del artículo Desarrollo de informes de SSRS en términos simples y, a continuación, desarrolle un informe de SSRS que solo muestre el primer carácter de los nombres de los autores ocultando el resto mediante el enmascaramiento de datos parcial.
2. Intente crear una base de datos de muestra a la que se hace referencia en el artículo Creación e implementación de múltiples versiones de la base de datos a través de instantáneas de esquema y luego cree un usuario de prueba llamado Estudiante y aplique el enmascaramiento de datos dinámico adecuado para ocultar las marcas de todos los estudiantes para este usuario de prueba.
3. Intente crear y eliminar el enmascaramiento de datos dinámicos para asegurarse de que puede agregar y eliminar correctamente el enmascaramiento de datos dinámicos en una tabla SQL.