記一次批量處理資料庫中的敏感資訊
阿新 • • 發佈:2020-08-14
前言
對於一些敏感資料,往往會對其加密後再入庫,這個是對資料安全性的一個最為簡單的措施。
最常見的莫過於手機號碼和身份證號了,相信還是有不少公司對這些敏感資訊是明文儲存的。
萬一被別人發現系統漏洞,或者是被拖庫,那基本上就涼涼了。
老黃最近也是發現了公司內部一個系統有這樣的問題,剛發現的時候都嚇了我一跳,這麼赤裸裸的明文手機號和身份證號。
第一反應就是要把這兩個資料進行加密處理。
既然要加密處理,那麼正在使用的系統肯定就會受到影響,而且幾千萬資料,也不是幾分鐘就能搞定的。
這個系統用的資料庫是阿里雲的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
總結
設計系統的時候,資料安全還真的是不容小覷的,對一些敏感資訊還是要加密入庫的。
修改資料的過程中,也涉及到了兩個知識點,資料的批量插入和批量更新。
本文首發於我的個人公眾號 不才老黃 ,不定期釋出一些內容,有興趣的可以關注一下喲!