Зашифровать столбец в SQL Server? - PullRequest
4 голосов
/ 12 ноября 2009

У нас есть веб-приложение, которое мы хотели бы продемонстрировать потенциальным клиентам, но наш лучший способ сделать это - использовать существующие данные для полного опыта. Конечно, мы не хотим делать это с фактическими именами или адресами клиентов и т.д., видимыми в приложении. Есть ли в SQL Server простой способ рандомизации или шифрования varchar или текстового поля?

Ни один из этих столбцов в любом случае не является ключом, ни основным, ни внешним.

Ответы [ 7 ]

5 голосов
/ 23 сентября 2011

Это поздний ответ, но я не был удовлетворен поиском в интернете по этому вопросу. Вот пример, который будет перемешивать имя и фамилию в таблице клиентов для создания новых имен:

--Replace Customers with your table name
select * from Customers

--Be sure int match your id column datatype
Declare @id int

--Add a WHERE here to select just a subset of your table
DECLARE mycursor CURSOR FOR SELECT id FROM Customers
OPEN mycursor
FETCH NEXT FROM mycursor INTO @id;

WHILE (@@FETCH_STATUS = 0) 
BEGIN
    --We loop
    --Warning: NEWID() is generated once per query, so we update the fullname in two queries.
    UPDATE Customers
        SET FirstName = (SELECT TOP 1 FirstName FROM Customers ORDER BY NEWID())
    WHERE id = @id
    UPDATE Customers
        SET LastName = (SELECT TOP 1 LastName FROM Customers ORDER BY NEWID())
    WHERE id = @id
    FETCH NEXT FROM mycursor INTO @id;
END

CLOSE mycursor;
DEALLOCATE mycursor;

select * from Customers
3 голосов
/ 12 ноября 2009

Redgate имеет инструмент для него: http://www.red -gate.com / products / SQL_Data_Generator / index.htm

Не использовал, но инструменты redgate очень хороши.

EDIT

Он генерирует данные, а не скремблирует, но все же может быть полезен.

2 голосов
/ 12 ноября 2009

Я шифровал данные один раз, меняя буквы в поле. Итак, если у вас есть имя «Майк Смит», и вы меняете все числа «я» на «О», «М» на «Я», «Е» на «А», «С» на «Т», в итоге вы получите

Moke Smoth
Loke Sloth
Loka Sloth
Loka Tloth
Loka Rrlorrh

этого было достаточно, чтобы сделать имя нечитаемым, а также вы не можете вернуться и определить, что это было (я изменил некоторые буквы, в которых уже были изменены буквы). Но, это все еще вроде читабельно.

0 голосов
/ 14 сентября 2016

Вот пара простых методов, которые имеют довольно хорошую производительность и могут быть применены к таблице:

use master;

declare @length as  int = 50;   --acts as maximum length for random length expressions
declare @rows   as  int = 10;

SELECT 
    CONVERT( VARCHAR(max), crypt_gen_random( @length     ))                                 as  FixedLengthText
,   CONVERT(NVARCHAR(max), crypt_gen_random( @length * 2 ))                                 as  FixedLengthUnicode
,   (   select crypt_gen_random((@length/8*6)) 
        where value."type" is not null  --refer to outer query, to get different value for each row
        FOR XML PATH(''))                                                                   as  FixedLengthBase64
,   CONVERT( VARCHAR(max), crypt_gen_random( (ABS(CHECKSUM(NewId())) %  @length     )+1 ))  as  RandomLengthText
,   CONVERT(NVARCHAR(max), crypt_gen_random( (ABS(CHECKSUM(NewId())) % (@length * 2))+1 ))  as  RandomLengthUnicode
,   (   select crypt_gen_random( ( (ABS(CHECKSUM(NewId())) % @length )+1 )/8*6 )
        where value."type" is not null  --refer to outer query, to get different value for each row
        FOR XML PATH(''))                                                                   as  RandomLengthBase64
FROM  dbo.spt_values  AS  value
WHERE   value."type" = 'P'  --Limit "number" to integers between 0-2047
    and value.number <= @rows
;
0 голосов
/ 18 мая 2015

В dbForge есть бесплатный инструмент для генерации данных: http://www.devart.com/dbforge/sql/data-generator/

0 голосов
/ 15 ноября 2009

Невозможно просто оставить ваши данные в таблицах и каким-то образом отобразить их только в зашифрованном виде.

Вы можете либо заменить данные, зашифровав их каким-либо образом, сгенерировать новые данные в том же общем виде, написать функцию (CLR или T-SQL), которая скремблирует их как часть используемых вами запросов, или зашифровать данные, в этом случае они могут отображаться только в том случае, если у пользователя также есть соответствующий ключ дешифрования.

Если вы решите заменить данные, в дополнение к ранее упомянутому инструменту Red Gate, вы можете также рассмотреть возможность использования генератора данных, поставляемого с Visual Studio Team Database, или, возможно, Integration Services. Последнее может быть особенно полезно, если вы выиграете от более сложных преобразований.

0 голосов
/ 12 ноября 2009

Вы можете создать список столбцов, которые необходимо обновить, а затем просто выполнить итерацию по указанному списку и выполнить некоторый динамический sql, который каким-то образом обновит строку. Я сделал довольно простую функцию скремблирования, которая будет просто обрабатывать данные (со случайной солью), чтобы они были достаточно безопасными для большинства целей.

if exists (select 1 where object_id('tempdb..#columnsToUpdate') is not null)
begin
    drop table #columnsToUpdate
end
create table #columnsToUpdate(tableName varchar(max), columnName varchar(max), max_length int)

if exists (select 1 where object_id('fnGetSanitizedName') is not null)
begin 
    drop function fnGetSanitizedName
end

if exists (select 1 where object_id('random') is not null)
begin 
    drop view random
end

if exists (select 1 where object_id('randUniform') is not null)
begin 
    drop function randUniform
end

GO

create view random(value) as select rand();
go

create function dbo.randUniform() returns real
begin
    declare @v real
    set @v = (select value from random)
    return @v
end

go

CREATE FUNCTION dbo.fnGetSanitizedName 
(
    @functionName nvarchar(max),
    @length int
)
RETURNS varchar(max)
AS
BEGIN
    return left(SUBSTRING(master.dbo.fn_varbintohexstr(HashBytes('SHA1', cast(cast(cast(dbo.randUniform() * 10000 as int) as varchar(8)) as varchar(40)) + @functionName)), 3, 32), @length)

END
GO

begin transaction
set nocount on

insert into #columnsToUpdate
select tables.name, columns.name, 
    case
        when types.name = 'nvarchar' then columns.max_length / 2
        else columns.max_length
    end as max_length
from sys.tables tables
inner join sys.columns columns on tables.object_id=columns.object_id
inner join sys.types types on columns.system_type_id = types.system_type_id
where types.name in ('nvarchar', 'varchar')


declare @tableName varchar(max)
declare @columnName varchar(max)
declare @length int
declare @executingSql varchar(max)

declare tableUpdateCursor cursor 
    for select tableName, columnName, max_length from #columnsToUpdate
open tableUpdateCursor

    fetch next from tableUpdateCursor into @tableName, @columnName, @length
    while @@fetch_status = 0
    begin
        set @executingSql = 'update ' + @tableName + ' set ' + @columnName + ' = dbo.fnGetSanitizedName(' + @columnName + ',' + cast(@length as varchar(max)) + ')'
        print @executingSql
        exec(@executingSql)

        fetch next from tableUpdateCursor into @tableName, @columnName, @length
    end


close tableUpdateCursor
deallocate tableUpdateCursor

set nocount off

rollback -- Can remove the rollback when you are sure about what your are doing.

drop table #columnsToUpdate
drop function dbo.fnGetSanitizedName
drop view random
drop function randUniform
...