Ten artykuł zawiera szczegółowe informacje na temat dynamicznego maskowania danych w SQL Server wraz z jego przypadkami użycia, najlepszymi praktykami i implikacjami bezpieczeństwa dla zaawansowanych użytkowników SQL (w tym programistów i testerów). Dodatkowo czytelnicy tego artykułu zapoznają się ze stosowaniem różnych typów dynamicznego maskowania danych. Artykuł podkreśla również znaczenie zaawansowanego wykorzystania maskowania danych w codziennych zadaniach związanych z tworzeniem i testowaniem baz danych.
Wymagania wstępne
Przejrzyjmy najpierw wymagania wstępne dotyczące tego artykułu.
Znajomość T-SQL
W tym artykule założono, że czytelnicy są dobrze zaznajomieni ze skryptami T-SQL i mogą wygodnie pisać i uruchamiać zapytania SQL w celu przeglądania i manipulowania bazami danych SQL.
Podstawy dynamicznego maskowania danych
W tym artykule założono również, że czytelnicy znają podstawowe koncepcje dynamicznego maskowania danych w SQL Server. Zapoznaj się z artykułem Maskowanie danych w SQL Server dla początkujących, aby zapoznać się z podstawami dynamicznego maskowania danych, jeśli jeszcze tego nie zrobiłeś.
Kompatybilność z bazą danych Azure SQL lub SQL Server 2016
Funkcja dynamicznego maskowania danych jest dostępna w SQL Server 2016 do SQL Server 2019, dlatego zdecydowanie zaleca się posiadanie jednego z następujących elementów:
1. Baza danych Azure SQL
2. SQL Server 2016 zainstalowany lokalnie lub zdalnie.
Konfigurowanie przykładowej bazy danych
Pamiętaj, aby utworzyć przykładową bazę danych przy użyciu następującego skryptu T-SQL zgodnego z SQL Server 2016 lub jako Azure SQL Database, jeśli chcesz postępować zgodnie z instrukcją w tym artykule:
-- 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
Sprawdzanie danych
Sprawdź nowo utworzoną i zapełnioną przykładową bazę danych ITSalesV2, uruchamiając następujący skrypt:
-- View monthly sales data SELECT s.SaleId ,s.SellingDate ,s.Customer ,s.Email ,s.Product ,s.TotalPrice FROM dbo.MonthlySale s
Dane wyjściowe są następujące:
Tworzenie nieuprzywilejowanego użytkownika
Utwórz nieuprzywilejowanego użytkownika bez logowania, który ma tylko uprawnienie SELECT w tabeli MonthlySale, który będzie widział zamaskowane dane jako warunek wstępny tego artykułu. W tym celu użyj następującego skryptu:
-- Create DataUser to have Select access to MonthlySale table CREATE USER DataUser WITHOUT LOGIN; GRANT SELECT ON MonthlySale TO DataUser;
Tworzenie procedury sprawdzania stanu maskowania
W tym artykule założono również, że w przykładowej bazie danych znajduje się procedura składowana, która pokazuje nam stan dynamicznego maskowania danych kolumn w tabelach bazy danych:
-- 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
Typy dynamicznego maskowania danych
Istnieją cztery popularne typy dynamicznego maskowania danych w SQL Server:
1. Domyślne maski danych
2. Częściowe maski danych
3. Maski danych losowych
4. Niestandardowe maski danych ciągu
Teraz zaimplementujemy wszystkie cztery popularne typy dynamicznego maskowania danych.
Wdrażanie domyślnego maskowania danych
Domyślne maskowanie danych całkowicie ukrywa kolumnę przed nieautoryzowanym użytkownikiem, zakrywając wszystkie wartości kolumny specjalnym znakiem, co bardzo utrudnia odgadnięcie zawartości kolumny.
Wymagania biznesowe
Załóżmy teraz, że otrzymujesz wymaganie biznesowe, które mówi, że adresy e-mail klientów powinny być całkowicie ukryte (zamaskowane) ze względu na wrażliwość tych informacji.
Najlepszym sposobem spełnienia tego wymagania biznesowego jest zamaskowanie kolumny E-mail za pomocą dynamicznego maskowania danych (DDM).
Domyślne maskowanie danych adresu e-mail
Zmodyfikujemy tabelę, aby zamaskować adresy e-mail w następujący sposób:
--Default dynamic data masking of Email column ALTER TABLE MonthlySale ALTER COLUMN Email varchar(200) MASKED WITH (FUNCTION = 'default()');
Sprawdzanie statusu maskowania
Sprawdź stan dynamicznego maskowania danych, korzystając z następującej procedury składowanej opartej na skrypcie T-SQL, do którego odwołuje się dokumentacja firmy Microsoft:
-- Checking dynamic data masking status EXEC ShowMaskingStatus
Dane wyjściowe pokazują nam, które kolumny zostały pomyślnie zamaskowane:
Wyświetlanie kolumny e-mail jako użytkownik danych
Następnie wykonaj instrukcję Select, aby wyświetlić miesięczną sprzedaż (tabelę) jako użytkownik o niskich uprawnieniach o nazwie DataUser mający tylko uprawnienia wyboru w tabeli w następujący sposób:
-- 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;
Dane wyjściowe są następujące:
Implementacja częściowego maskowania danych
Częściowe maskowanie danych, jak sama nazwa wskazuje, częściowo ukrywa kolumnę przed wyświetleniem jej przez nieautoryzowanego użytkownika, zakrywając część wartości kolumny znakami specjalnymi, dzięki czemu zawartość kolumny jest nieco czytelna, ale nadal trudna do odgadnięcia.
Wymagania biznesowe
Teraz pomyśl o wymaganiu biznesowym, w którym zostałeś poproszony o częściowe ukrycie nazwy klientów w taki sposób, aby widoczny był tylko pierwszy znak nazwy. Najlepszym sposobem spełnienia tego wymagania biznesowego jest maskowanie kolumny Klient za pomocą częściowego maskowania danych dynamicznych.
Częściowe maskowanie danych nazw klientów
Zmienimy tabelę, aby częściowo zamaskować kolumnę Customer w następujący sposób:
-- Partial data masking of Customer names ALTER TABLE MonthlySale ALTER COLUMN [Customer] ADD MASKED WITH (FUNCTION = 'partial(1,"XXXXXXX",0)')
Sprawdzanie statusu maskowania
Sprawdź stan dynamicznego maskowania danych:
-- Checking dynamic data masking status EXEC ShowMaskingStatus
Dane wyjściowe pokazują nam, które kolumny zostały pomyślnie zamaskowane:
Wyświetlanie kolumny klienta jako użytkownika danych
Wyświetl tabelę jako użytkownik testowy DataUser, który musi zobaczyć zamaskowane dane:
-- 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;
Dane wyjściowe są następujące:
Wdrażanie maskowania danych losowych
Maskowanie danych losowych ukrywa kolumnę losowo przed nieautoryzowanym użytkownikiem, zakrywając kolumnę na podstawie zakresu wartości, co bardzo utrudnia odgadnięcie zawartości kolumny. Pamiętaj, że losowy typ maskowania danych ma zastosowanie tylko do kolumn, które przechowują tylko liczby i można go określić, podając zakres losowości.
Wymagania biznesowe
Otrzymujesz wymóg biznesowy, który stanowi, że cena produktu powinna być zamaskowana losowym zakresem liczb, aby użytkownicy z niskimi uprawnieniami nie mogli znać dokładnych cen produktu ze względu na ochronę prywatności. Najlepszym sposobem spełnienia tej specyfikacji biznesowej jest maskowanie kolumny TotalPrice za pomocą losowego dynamicznego maskowania danych.
Maskowanie danych losowych w kolumnie TotalPrice
Zmień tabelę MonthlySale, aby losowo zamaskować TotalPrice w następujący sposób:
--Random dynamic data masking of TotalPrice column ALTER TABLE MonthlySale ALTER COLUMN [TotalPrice] decimal(10,2) MASKED WITH (FUNCTION = 'random(1, 12)')
Sprawdzanie statusu maskowania
Sprawdź stan dynamicznego maskowania danych, uruchamiając następującą procedurę składowaną:
-- Checking dynamic data masking status EXEC ShowMaskingStatus
Dane wyjściowe pokazują nam, które kolumny zostały pomyślnie zamaskowane:
Wyświetlanie kolumny TotalPrice jako DataUser
Wyświetl tabelę jako użytkownik danych teraz:
-- 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;
Dane wyjściowe są następujące:
Pamiętaj, że dane wyjściowe w kolumnie Maskowanie danych losowych mogą się różnić ze względu na generowanie liczb losowych.
Implementacja niestandardowego maskowania danych ciągu
Niestandardowe maskowanie danych ciągu, jak sama nazwa wskazuje, dodaje niestandardowy znak, aby ukryć kolumnę, co bardzo utrudnia odgadnięcie jej zawartości. Należy pamiętać, że niestandardowe maskowanie danych ciągu jest używane w połączeniu z częściowym maskowaniem danych poprzez dostosowanie znaku w celu zamaskowania rzeczywistych wartości kolumn. Innymi słowy, niestandardowe maskowanie danych ciągów jest rozszerzoną formą częściowego maskowania danych.
Wymagania biznesowe
Rozważ wymóg biznesowy, aby pokazywać tylko pierwszy i ostatni znak kolumny Produkt, podczas gdy pozostałe znaki powinny być ukryte lub zamaskowane myślnikami (-). Najlepszym sposobem na spełnienie tej specyfikacji biznesowej jest zamaskowanie kolumny Produkt za pomocą częściowego maskowania danych dynamicznych za pomocą wymaganego niestandardowego ciągu.
Maskowanie danych łańcucha klienta danych sprzedaży
Zmień tabelę MonthlySale, aby zamaskować kolumnę Product w następujący sposób:
--Custom string dynamic data masking of Product column ALTER TABLE MonthlySale ALTER COLUMN [Product] ADD MASKED WITH (FUNCTION = 'partial(1,"---",1)')
Sprawdzanie statusu maskowania
W tym momencie warto sprawdzić stan dynamicznego maskowania danych za pomocą następującego skryptu:
-- Checking dynamic data masking status EXEC ShowMaskingStatus
Dane wyjściowe pokazują wszystkie kolumny, w których zastosowano dynamiczne maskowanie danych, jak pokazano poniżej:
Wyświetlanie kolumny produktu jako użytkownik danych
Wyświetl tabelę jako użytkownik danych teraz:
-- 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;
Dane wyjściowe są następujące:
Gratulacje! Wszystkie cztery techniki maskowania zostały pomyślnie zaimplementowane.
Proszę zapoznać się z artykułem Maskowanie danych w SQL Server dla początkujących, aby usunąć zastosowane typy maskowania danych.
Najlepsze praktyki
Pamiętaj o następujących rzeczach:
1. Dynamiczne maskowanie danych nie chroni ani nie szyfruje danych w kolumnie, więc nie powinno być używane do tego celu.
2. Potencjalny użytkownik, który ma zobaczyć zamaskowane dane, musi mieć bardzo ograniczony dostęp do przeglądania danych i nie powinien w ogóle otrzymać uprawnienia do aktualizacji w celu wykorzystania danych.
3. Potencjalny użytkownik, nawet mający uprawnienia tylko SELECT, może uruchamiać wyczerpujące zapytania, aby odgadnąć poprawną wartość, więc uważaj na to.
4. Możesz również użyć opcji ALTER COLUMN Email ADD MASKED WITH (FUNCTION =’email()’) do maskowania kolumn e-mail zamiast używania domyślnego maskowania dynamicznego.
5. Możesz użyć niestandardowego maskowania danych ciągów, aby ukryć numer karty debetowej w raporcie transakcji, pokazując tylko ostatnie dwie lub cztery cyfry, tak jak widać to na rachunkach z zakupów.
Rzeczy do zrobienia
Teraz, gdy możesz wdrożyć wszystkie cztery rodzaje maskowania, spróbuj następujących rzeczy, aby jeszcze bardziej poprawić swoje umiejętności:
1. Utwórz przykładową bazę danych, postępując zgodnie z instrukcjami zawartymi w artykule Tworzenie raportów SSRS w prostych warunkach, a następnie opracuj raport SSRS, który pokazuje tylko pierwszy znak nazwisk Autorów, ukrywając resztę za pomocą częściowego maskowania danych.
2. Spróbuj utworzyć przykładową bazę danych, o której mowa w artykule Tworzenie i wdrażanie wielu wersji bazy danych za pomocą migawek schematu, a następnie utwórz użytkownika testowego o nazwie Student i zastosuj odpowiednie dynamiczne maskowanie danych, aby ukryć znaki wszystkich uczniów dla tego użytkownika testowego.
3. Spróbuj utworzyć i usunąć dynamiczne maskowanie danych, aby zapewnić pomyślne dodawanie i usuwanie dynamicznego maskowania danych w tabeli SQL.