我使用的是 SQL Server 2008。
我想对查询的输出数据进行字符屏蔽。
这是我在执行选择时从表上的列中获取的数据:
column1
384844033434
743423547878
111224678885
我想要这样的输出:
column1
384xxxxxx434
743xxxxxx878
111xxxxxx885
我该怎么做?
您必须使用视图,并拒绝所有用户对基础表的 SELECT 访问。
您的视图看起来像这样
SELECT
SUBSTRING(x.SecurityNumber,1,3) +
'xxxxx' +
SUBSTRING(x.SecurityNumber,LEN(x.SecurityNumber) - 2, LEN(x.SecurityNumber))
AS column1
FROM underlyingTable x
然后,您可以授予用户对此视图的 SELECT 访问权限,并按照您描述的方式屏蔽输出。
如果您希望客户端软件能够在此表中插入或更新数据,您可以使用 INSTEAD OF INSERT 或 INSTEAD OF UPDATE 触发器来更新基表。
从
SQL Server 2016+
您可以使用动态数据屏蔽功能。
动态数据屏蔽通过向非特权用户屏蔽敏感数据来限制敏感数据的暴露。动态数据屏蔽使客户能够指定要泄露的敏感数据量,同时对应用程序层的影响最小,从而有助于防止未经授权的访问敏感数据。它是一种数据保护功能,可隐藏对指定数据库字段的查询结果集中的敏感数据,而数据库中的数据不会发生更改。动态数据屏蔽很容易与现有应用程序一起使用,因为屏蔽规则应用于查询结果中。 许多应用程序可以在不修改现有查询的情况下屏蔽敏感数据。
CREATE TABLE #tab(ID INT IDENTITY(1,1), column1 VARCHAR(12));
INSERT INTO #tab(column1)
VALUES('384844033434'),('743423547878'),('111224678885');
SELECT * FROM #tab;
输出:
╔════╦══════════════╗
║ ID ║ column1 ║
╠════╬══════════════╣
║ 1 ║ 384844033434 ║
║ 2 ║ 743423547878 ║
║ 3 ║ 111224678885 ║
╚════╩══════════════╝
ALTER TABLE #tab
ALTER COLUMN column1 VARCHAR(12) MASKED WITH (FUNCTION = 'partial(3,"xxxxxx",3)');
SELECT * FROM #tab;
输出:
╔════╦══════════════╗
║ ID ║ column1 ║
╠════╬══════════════╣
║ 1 ║ 384xxxxxx434 ║
║ 2 ║ 743xxxxxx878 ║
║ 3 ║ 111xxxxxx885 ║
╚════╩══════════════╝
LiveDemo
如果您知道数据字段的长度,那么您可以使用其他答案将生成的静态版本,但您始终可以创建一个函数来生成此版本:
CREATE FUNCTION MixUpCharacters
(
@OrigVal varchar(max)
)
RETURNS varchar(max)
AS
BEGIN
DECLARE @NewVal varchar(max)
DECLARE @OrigLen int
DECLARE @LoopCt int
DECLARE @Part varchar(max) = ''
Declare @PartLength int
SET @NewVal = ''
SET @OrigLen = DATALENGTH(@OrigVal)
SET @LoopCt = 1
SET @Part = SUBSTRING(@OrigVal, 4, len(@OrigVal)-6)
set @PartLength = LEN(@Part)
WHILE @LoopCt <= @PartLength
BEGIN
-- Current length of possible characters
SET @NewVal = @NewVal + 'X'
-- Advance the loop
SET @LoopCt = @LoopCt + 1
END
Return REPLACE(@OrigVal, @Part, @NewVal)
END
对于此函数,您将传入要屏蔽的值。所以你的查询是:
declare @temp table
(
col1 varchar(50)
)
insert into @temp
values ('384844033434'), ('743423547878'), ('111224678885')
select dbo.MixUpCharacters(col1) col1
from @temp
结果将是:
| COL1 |
----------------
| 384XXXXXX434 |
| 743XXXXXX878 |
| 111XXXXXX885 |
或者这里有一种使用递归 CTE 的方法:
;with data(col1) as
(
select '384844033434'
union all
select '7434235878'
union all
select '111224678885'
),
s1 (col1, repfull) as
(
select col1,
SUBSTRING(col1, 4, len(col1)-6) repfull
from data
),
s2 (col1, item, repfull, r) as
(
select col1,
cast('x' as varchar(max)),
right(repfull, LEN(repfull)-1),
repfull
from s1
union all
select col1,
'x'+ cast(item as varchar(max)),
right(repfull, LEN(repfull)-1),
r
from s2
where len(repfull) >0
)
select REPLACE(col1, r, item) newValue
from
(
select col1, item, R,
ROW_NUMBER() over(partition by col1 order by len(item) desc) rn
from s2
) src
where rn = 1
一个简单的选择查询将只返回表中的内容,无论它是否加密。
所以,我认为你不能在数据库级别上执行此操作。
根据您的要求,您需要在应用程序中使用双向加密算法,以便您可以在将数据加密保存到数据库之前对数据进行加密,然后从数据库中获取加密信息并在您的应用程序中解密。
很简单兄弟
SELECT CONCAT (SUBSTR('Your string',1,3),LPAD(SUBSTR('Your string',-3),LENGTH('Your string')-1,'*')) RESULT FROM dual
输出:
你*****ing
如果是
num
类型转换为 char
如果您想屏蔽您不知道字段长度的字段。你可以像这样升级bluefeet的代码:
ALTER FUNCTION MixUpCharacters
(
@OrigVal varchar(MAX)
)
RETURNS varchar(MAX)
AS
BEGIN
DECLARE @NewVal NVARCHAR(MAX)
DECLARE @OrigLen INT
DECLARE @LoopCt INT
DECLARE @Part NVARCHAR(MAX) = ''
DECLARE @PartLength INT -- MastLength
DECLARE @PartStartIndex INT -- MaskStartIndex
SET @NewVal = ''
SET @LoopCt = 1
SET @OrigLen = LEN(@OrigVal)
IF(@OrigLen = 1)
BEGIN
RETURN 'X'
END
IF(@OrigLen < 6)
BEGIN
SET @PartStartIndex = @OrigLen / 2
SET @PartLength = @OrigLen - @PartStartIndex
SET @Part = SUBSTRING(@OrigVal, @PartStartIndex, @PartLength)
END
ELSE IF(@OrigLen < 8)
BEGIN
SET @PartStartIndex = 3
SET @PartLength = @OrigLen - @PartStartIndex - 1
SET @Part = SUBSTRING(@OrigVal, @PartStartIndex, @PartLength)
END
ELSE
BEGIN
SET @PartStartIndex = 4
SET @PartLength = @OrigLen - @PartStartIndex - 2
SET @Part = SUBSTRING(@OrigVal, @PartStartIndex, @PartLength)
END
WHILE @LoopCt <= @PartLength
BEGIN
-- Current length of possible characters
SET @NewVal = @NewVal + 'X'
-- Advance the loop
SET @LoopCt = @LoopCt + 1
END
RETURN REPLACE(@OrigVal, @Part, @NewVal)
END
你可以这样测试:
SELECT dbo.MixUpCharacters('1')
UNION ALL
SELECT dbo.MixUpCharacters('12')
UNION ALL
SELECT dbo.MixUpCharacters('123')
UNION ALL
SELECT dbo.MixUpCharacters('1234')
UNION ALL
SELECT dbo.MixUpCharacters('12345')
UNION ALL
SELECT dbo.MixUpCharacters('123456')
UNION ALL
SELECT dbo.MixUpCharacters('1234567')
UNION ALL
SELECT dbo.MixUpCharacters('12345678')
UNION ALL
SELECT dbo.MixUpCharacters('123456789')
UNION ALL
select dbo.MixUpCharacters('1234567890')
UNION ALL
select dbo.MixUpCharacters('12345678910')
结果:
X
X2
XX3
1XX4
1XXX5
12XX56
12XXX67
123XX678
123XXX789
123XXXX890
123XXXXX910
这也适用于检索时屏蔽输出。
SELECT CONCAT(SUBSTRING(column1, 1, 3),'xxxxxx',SUBSTRING(column1, 10, 3)) FROM tableName;
如果值长度不固定,可以使用下面的。
SELECT CONCAT(SUBSTRING(column1, 1, 3),'xxxxxx',SUBSTRING(column1, LEN(column1)-2, 3)) FROM tableName;
concat('XXXXXXXXX',right(aadharno,4)) as aadharno
它将掩盖 aadhar 号码,从右数第四个。
concat('XXXXXXXXX',right(aadharno,4)) as aadharno
它将掩盖 aadhar 号码。
输出将类似于:
XXXXXXXXX7995
如果您有固定长度的数据(即手机/手机号码或出生日期),您可以使用 SQL Server 的
LEFT
和 RIGHT
功能来屏蔽输入
SELECT LEFT(YourColumnName, NoOfCharsToDisplayFirst) + 'maskcharacters'+ RIGHT(YourColumnName, NoOfCharsToDisplayLast) AS MaskedString;
示例:
SELECT LEFT('9876543210', 3) + 'xxxxxx'+ RIGHT('9876543210', 3) AS MaskedString;
输出:
987xxxxxx210