记一次批量处理数据库中的敏感信息
前言
对于一些敏感数据,往往会对其加密后再入库,这个是对数据安全性的一个最为简单的措施。
最常见的莫过于手机号码和身份证号了,相信还是有不少公司对这些敏感信息是明文存储的。
万一被别人发现系统漏洞,或者是被拖库,那基本上就凉凉了。
老黄最近也是发现了公司内部一个系统有这样的问题,刚发现的时候都吓了我一跳,这么赤裸裸的明文手机号和身份证号。
第一反应就是要把这两个数据进行加密处理。
既然要加密处理,那么正在使用的系统肯定就会受到影响,而且几千万数据,也不是几分钟就能搞定的。
这个系统用的数据库是阿里云的RDS(SQL Server)。
下面简单说一下老黄这边的处理方案。
如何处理
整个处理的流程是分了三个步骤:
- 修改数据库中的字段长度
- 系统要更新一个版本做兼容处理,写入要用统一的加密方法,读取的时候,要加一个长度判断,当长度大于20的时候,需要进行解密操作,这样才能确保不会把密文直接展示出去。
- 修改数据
之前数据库给这两个字段设置的长度都是20,现在统一调整成150。
公司内部已经统一了一套加解密方法了,所以系统调整这一块是比较简单的,统一在数据层处理。
剩下的就是去数据库改数据了。
统一的加密方法,在数据库中没有办法直接使用,所以只能单独写个程序去处理。
改数据也细分为下面3步。
- 读取源数据,加密相关字段
- 将加密的数据写入到一张临时表中
- 根据临时表去更新源表的相关字段
这里的最为核心的一个就是批量写入和批量更新。如果一条条更新,那不知道要等多久才能全部处理完。
先是写一个控制台程序,根据Id分批次,把加密好的数据,以五千条一次写入的频率,一百万数据当成一个批次。
var flag = true;
var begin = 0;
var tmpEnd = begin + 5000;
var end = 1000000;
while (flag)
{
// 省略读取数据
foreach (var item in list)
{
DataRow dr = dt.NewRow();
dr["Id"] = item.Id;
dr["IDCard"] = GetEncryptValue(item.IDCard ?? "");
dr["PhoneNo"] = GetEncryptValue(item.PhoneNo ?? "");
dr["IDCardRaw"] = item.IDCard ?? "";
dr["PhoneNoRaw"] = item.PhoneNo ?? "";
dt.Rows.Add(dr);
}
using (SqlConnection conn = new SqlConnection(connStr))
{
conn.Open();
SqlBulkCopy bulkCopy = new SqlBulkCopy(conn);
bulkCopy.DestinationTableName = "enc_tmp";
bulkCopy.BatchSize = dt.Rows.Count;
bulkCopy.WriteToServer(dt);
}
begin = tmpEnd;
tmpEnd += 5000;
if (tmpEnd >= end || list == null || !list.Any())
{
flag = false;
}
Console.WriteLine(begin);
}
为保证写入的速度,先不要在那个临时表建索引,等数据写进去后再给Id建索引。
把数据写进临时表后,下面就是直接用SQL脚本来批量更新了。
-- 建索引
create index idx_enc_tmp_id on enc_tmp (id)
-- 批量更新
update dbo.yourtable
set PhoneNo= a.PhoneNo, IDCard = a.IDCard
from dbo.yourtable b
inner join dbo.enc_tmp a
on a.id=b.id
-- 这里更新要看数据库的配置,如果配置高,可以一次更新,不然就建议25万或50万一个批次
-- where a.id >= 0 and a.id <= 500000
-- 查询校验一下
SELECT top 100 [id]
,[IDCard]
,[PhoneNo]
FROM dbo.yourtable WITH (NOLOCK)
where id > 0 and id <= 500000
order by id asc
-- 清除临时表的数据
truncate table dbo.enc_tmp
-- 删除索引
drop index idx_enc_tmp_id on enc_tmp
总结
设计系统的时候,数据安全还真的是不容小觑的,对一些敏感信息还是要加密入库的。
修改数据的过程中,也涉及到了两个知识点,数据的批量插入和批量更新。
本文首发于我的个人公众号 不才老黄 ,不定期发布一些内容,有兴趣的可以关注一下哟!
如果您认为这篇文章还不错或者有所收获,可以点击右下角的【推荐】按钮,因为你的支持是我继续写作,分享的最大动力!
声明:
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。如果您发现博客中出现了错误,或者有更好的建议、想法,请及时与我联系!!如果想找我私下交流,可以私信或者加我微信。