Có cách nào nhanh chóng để tìm tất cả các cột trong SQL Server 2008 R2 được mã hóa / có dữ liệu được mã hóa không?


10

Có cách nào nhanh chóng để tìm tất cả các cột trong SQL Server 2008 R2 được mã hóa / có dữ liệu được mã hóa không?

Tôi cần phải vô hiệu hóa dữ liệu trong tất cả các cột được mã hóa trong một máy chủ phát triển (theo quy tắc kinh doanh của chúng tôi). Tôi biết hầu hết các cột vì chúng tôi sử dụng chúng thường xuyên, nhưng tôi muốn kỹ lưỡng và tôi cũng muốn chứng minh rằng tôi đã tìm thấy tất cả.

Tôi đã tìm kiếm trên web, tìm trong Information_SCHema và kiểm tra DMV mà tôi nghĩ sẽ hữu ích và cả sys.columnssys.objects - nhưng cho đến nay không gặp may.


1
Chúng tôi lười biếng ở đây và đã tính toán các cột sử dụng autodecryptbyvoodoo. Nếu bạn có một cái gì đó tương tự, thì bạn có thể xem xét các định nghĩa cột cho điều đó
billinkc

Câu trả lời:


10

Giả sử bạn đang nói về dữ liệu được mã hóa bằng các khóa SQL Server, có nhiều cách để tìm các cột này.

Các Key_name()chức năng sẽ trở lại với tên của khóa dùng để mã hóa cho rằng giá trị cụ thể và sẽ trở lại NULL nếu không có bất cứ điều gì được mã hóa với một phím "nổi tiếng" (bên thứ 3, hoặc đơn giản không được mã hóa).

Với kiến ​​thức đó, chúng ta có thể kiểm tra mọi cột để xem nó có chứa ít nhất một hàng có giá trị phương sai trả về tên khóa không

chức năng của key_name ()

--create a test database
CREATE DATABASE [Test_ENCR]
GO

--change context
USE [Test_ENCR]
GO


--because it's possible to encrypt different rows with different keys I'll create 2 keys for this demo
-- Create a symmetric key
CREATE SYMMETRIC KEY symmetricKey1
   WITH ALGORITHM = AES_128
   ENCRYPTION BY PASSWORD = 'password01!';
GO

-- Create a second key
CREATE SYMMETRIC KEY symmetricKey2 
   WITH ALGORITHM = AES_128
   ENCRYPTION BY PASSWORD = 'password02!';
GO



--create a table that will have a column holding:
--1: encrypted row with key1
--2: encrypted row with key2
--3: a non encrypted just varbinary value

CREATE TABLE encryptedTable
(ID int IDENTITY PRIMARY KEY,
EncryptedCol varbinary(256) NOT NULL);
GO


-- open key1
OPEN SYMMETRIC KEY symmetricKey1 
    DECRYPTION BY PASSWORD = 'password01!';
GO

-- open key2
OPEN SYMMETRIC KEY symmetricKey2 
    DECRYPTION BY PASSWORD = 'password02!';
GO

--insert encrypted data with key1
INSERT INTO encryptedTable(encryptedCol)
VALUES ( ENCRYPTBYKEY (Key_GUID('symmetricKey1'), 'EncryptedText1'));
GO

--insert encrypted data with key2
INSERT INTO encryptedTable(encryptedCol)
VALUES ( ENCRYPTBYKEY (Key_GUID('symmetricKey2'), 'EncryptedText2'));
GO


--insert just varbinary data
INSERT INTO encryptedTable(encryptedCol)
VALUES (CONVERT(varbinary(256),'NotEncryptedTextJustVarBinary'))



--have a look, without the key, all varbinary for you.
SELECT * FROM encryptedTable
GO

các kết quả:

nhập mô tả hình ảnh ở đây

--Return all key_names
SELECT DISTINCT     key_name(encryptedcol), 
                    EncryptedCol 
FROM encryptedTable;

các kết quả:

nhập mô tả hình ảnh ở đây

Làm thế nào để thực hiện nó để tìm các cột được mã hóa

--How do we dynamically find all the columns that have at least one row with a encrypted value?

-- first we will find all tables and column with a varbinary datatype
-- then we will test all those columns with a simple select
-- If the key_name() function returns a value, the column and table name are stored together with the keyname

--create a table to hold all varbinary columns and tables
CREATE TABLE #TablesWithVarbinCols (    ID int IDENTITY,
                                TableName nvarchar(128),
                                ColumnName nvarchar(128)
                                );

--create a table to hold the end result
CREATE TABLE #TablesWithEncryption (
                                TableName nvarchar(128),
                                ColumnName nvarchar(128),
                                KeyName varchar(128)
                                );


--find and store all table and column names of user tables containing a varbinary column
INSERT INTO #TablesWithVarbinCols (TableName,ColumnName)
SELECT      o.[name] as TableName,
            c.[name] as ColumnName
FROM        sys.objects o
INNER JOIN  sys.columns c
ON          o.[object_id]=c.[object_id] 
INNER JOIN  sys.types t
ON          c.system_type_id=t.system_type_id
WHERE       o.[type]='U'
AND         t.name=N'varbinary'
AND         c.max_length > -1;


DECLARE @col nvarchar(256)
DECLARE @tab nvarchar(256)
DECLARE @c int = 1
DECLARE @MaxC int
DECLARE @SQL varchar(max)

SELECT @MaxC=MAX(ID)
FROM #TablesWithVarbinCols

--loop the previous result and create a simple select statement with a key_name() is not null where clause. 
--If you have a result, store the details
WHILE @c <= @MaxC
BEGIN
    SELECT  @Tab=TableName,
         @col=ColumnName
    FROM    #TablesWithVarbinCols
    WHERE   ID=@c

    SET @SQL='  INSERT INTO #TablesWithEncryption (TableName, ColumnName, KeyName)
                SELECT DISTINCT '''+@Tab +''',''' +@col +''', key_name('+@Col +') from '+ @tab +' 
                WHERE key_name('+@Col +') is not null;'
    exec (@SQL)

    DELETE
    FROM #TablesWithVarbinCols
    WHERE id=@c;
    SET @c=@c+1
END

--select the result
SELECT * FROM #TablesWithEncryption;

các kết quả:

nhập mô tả hình ảnh ở đây

--cleanup
DROP TABLE #TablesWithVarbinCols;
DROP TABLE #TablesWithEncryption;

8

Vấn đề với mã hóa cấp độ tế bào là bản thân cột không thực sự được mã hóa, đó là dữ liệu chứa trong cột đó. Bản thân các cột chỉ là các cột khác nhau (vì đó là những gì bắt buộc) và có thể chứa dữ liệu hoàn toàn dễ đọc. Đó là việc sử dụng ENCRYPTBY*và các DECRYPTBY*chức năng thực sự làm cho dữ liệu được mã hóa.

Bạn có thể bắt đầu bằng cách truy vấn đơn giản khung nhìn sys.columns cho tất cả các cột là varbinary:

select
  object_name(a.object_id) [objectname]
  ,a.name [columnname]
  ,a.column_id
from
   sys.columns a
   join sys.types b on (a.system_type_id = b.system_type_id)
where
   b.name = N'varbinary';

Mặt khác, bạn sẽ cần xem lại mã của mình để xác định nơi các chức năng mã hóa / giải mã đang được sử dụng:

select
   object_name(object_id) [objectname]
   ,definition
from
   sys.sql_modules
where
   definition like N'%ENCRYPT%' 
   OR definition like N'%DECRYPT%';


1

Bạn có thể tìm thấy các cột được mã hóa bằng khóa \ chứng chỉ bằng cách tìm kiếm tất cả các cột khác nhau và kiểm tra khóa mã hóa bằng chức năng KEY_NAME.

Tuy nhiên, quá trình này hơi tốn kém và mất thời gian. Nếu bạn cần tìm các cột này một cách thường xuyên, tôi khuyên bạn nên "gắn thẻ" các cột có thuộc tính mở rộng. Chúng tôi có thể xây dựng dựa trên giải pháp của Edward tổng hợp và "gắn thẻ" các cột được tìm thấy với các thuộc tính mở rộng như mã hóa, mã hóa và mã hóa.

--create a table to hold all varbinary columns and tables
CREATE TABLE #TablesWithVarbinCols (    ID int IDENTITY,
                            SchemaName nvarchar(128),
                            TableName nvarchar(128),
                            ColumnName nvarchar(128)
                            );

--find and store all table and column names of user tables containing a 
varbinary column
INSERT INTO #TablesWithVarbinCols (SchemaName,TableName,ColumnName)
SELECT      s.[name] as SchemaName,
            o.[name] as TableName,
            c.[name] as ColumnName
FROM        sys.objects o
INNER JOIN  sys.schemas s
ON          s.[schema_id] = o.[schema_id]
INNER JOIN  sys.columns c
ON          o.[object_id]=c.[object_id] 
INNER JOIN  sys.types t
ON          c.system_type_id=t.system_type_id
WHERE       o.[type]='U'
AND         t.name=N'varbinary'
AND         c.max_length > -1;

DECLARE @sch nvarchar(128)
DECLARE @col nvarchar(256)
DECLARE @tab nvarchar(256)
DECLARE @key nvarchar(256)
DECLARE @cert nvarchar(256)
DECLARE @c int = 1
DECLARE @MaxC int
DECLARE @SQL nvarchar(max)

SELECT @MaxC=MAX(ID)
FROM #TablesWithVarbinCols

--loop the previous result and create a simple select statement with a 
key_name() is not null where clause. 
--If you have a result, store the details
WHILE @c <= @MaxC
BEGIN
    SET @key = NULL;
    SELECT  @sch=SchemaName,
            @Tab=TableName,
            @col=ColumnName
    FROM    #TablesWithVarbinCols
    WHERE   ID=@c


SET @SQL='SELECT DISTINCT @key= key_name('+@Col +') from '+ @tab +' 
            WHERE key_name('+@Col +') is not null;'


exec sp_executesql @SQL, N'@key nvarchar(256) out', @key out

SELECT @cert =  c.name 
from sys.symmetric_keys sk
join sys.key_encryptions ke
    on
    sk.symmetric_key_id= ke.key_id
join sys.certificates c
    on
    ke.thumbprint=c.thumbprint
where sk.name = @key


IF (@key IS NOT NULL)
BEGIN

    SET @SQL=
    'EXEC sp_addextendedproperty @name = N''encrypted'', @value = N''1'', '+
    '@level0type = N''Schema'', @level0name = '''+@Sch+''', '+
    '@level1type = N''Table'', @level1name = '''+@tab+''','+
    '@level2type = N''Column'', @level2name = '''+@col+'''
    '

    EXEC sp_executesql @SQL

    SET @SQL=
    'EXEC sp_addextendedproperty @name = N''encryptkey'', @value = '''+@key+''', '+
    '@level0type = N''Schema'', @level0name = '''+@Sch+''', '+
    '@level1type = N''Table'', @level1name = '''+@tab+''','+
    '@level2type = N''Column'', @level2name = '''+@col+'''
    '

    EXEC sp_executesql @SQL

    SET @SQL=
    'EXEC sp_addextendedproperty @name = N''encryptcert'', @value = '''+@cert+''', '+
    '@level0type = N''Schema'', @level0name = '''+@Sch+''', '+
    '@level1type = N''Table'', @level1name = '''+@tab+''','+
    '@level2type = N''Column'', @level2name = '''+@col+'''
    '

    EXEC sp_executesql @SQL

END

DELETE
FROM #TablesWithVarbinCols
WHERE id=@c;
SET @c=@c+1

END

drop table #TablesWithVarbinCols

Sau đó, chúng ta có thể dễ dàng tìm thấy các cột được mã hóa bằng cách tìm kiếm các thuộc tính mở rộng.

--Adjust WHERE clause depending on what tags you are looking for
SELECT
   SCHEMA_NAME(tbl.schema_id) AS SchemaName,    
   tbl.name AS TableName, 
   clmns.name AS ColumnName,
  p.name AS ExtendedPropertyName,    --remove for programming
   CAST(p.value AS sql_variant) AS ExtendedPropertyValue
FROM
   sys.tables AS tbl
   INNER JOIN sys.all_columns AS clmns ON clmns.object_id=tbl.object_id
   INNER JOIN sys.extended_properties AS p ON p.major_id=tbl.object_id AND p.minor_id=clmns.column_id AND p.class=1
WHERE p.name in ('encrypted','encryptkey','encryptcert')
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.