记一次批量处理数据库中的敏感信息
前言
對(duì)于一些敏感數(shù)據(jù),往往會(huì)對(duì)其加密后再入庫,這個(gè)是對(duì)數(shù)據(jù)安全性的一個(gè)最為簡單的措施。
最常見的莫過于手機(jī)號(hào)碼和身份證號(hào)了,相信還是有不少公司對(duì)這些敏感信息是明文存儲(chǔ)的。
萬一被別人發(fā)現(xiàn)系統(tǒng)漏洞,或者是被拖庫,那基本上就涼涼了。
老黃最近也是發(fā)現(xiàn)了公司內(nèi)部一個(gè)系統(tǒng)有這樣的問題,剛發(fā)現(xiàn)的時(shí)候都嚇了我一跳,這么赤裸裸的明文手機(jī)號(hào)和身份證號(hào)。
第一反應(yīng)就是要把這兩個(gè)數(shù)據(jù)進(jìn)行加密處理。
既然要加密處理,那么正在使用的系統(tǒng)肯定就會(huì)受到影響,而且?guī)浊f數(shù)據(jù),也不是幾分鐘就能搞定的。
這個(gè)系統(tǒng)用的數(shù)據(jù)庫是阿里云的RDS(SQL Server)。
下面簡單說一下老黃這邊的處理方案。
如何處理
整個(gè)處理的流程是分了三個(gè)步驟:
修改數(shù)據(jù)庫中的字段長度
系統(tǒng)要更新一個(gè)版本做兼容處理,寫入要用統(tǒng)一的加密方法,讀取的時(shí)候,要加一個(gè)長度判斷,當(dāng)長度大于20的時(shí)候,需要進(jìn)行解密操作,這樣才能確保不會(huì)把密文直接展示出去。
修改數(shù)據(jù)
之前數(shù)據(jù)庫給這兩個(gè)字段設(shè)置的長度都是20,現(xiàn)在統(tǒng)一調(diào)整成150。
公司內(nèi)部已經(jīng)統(tǒng)一了一套加解密方法了,所以系統(tǒng)調(diào)整這一塊是比較簡單的,統(tǒng)一在數(shù)據(jù)層處理。
剩下的就是去數(shù)據(jù)庫改數(shù)據(jù)了。
統(tǒng)一的加密方法,在數(shù)據(jù)庫中沒有辦法直接使用,所以只能單獨(dú)寫個(gè)程序去處理。
改數(shù)據(jù)也細(xì)分為下面3步。
讀取源數(shù)據(jù),加密相關(guān)字段
將加密的數(shù)據(jù)寫入到一張臨時(shí)表中
根據(jù)臨時(shí)表去更新源表的相關(guān)字段
這里的最為核心的一個(gè)就是批量寫入和批量更新。如果一條條更新,那不知道要等多久才能全部處理完。
先是寫一個(gè)控制臺(tái)程序,根據(jù)Id分批次,把加密好的數(shù)據(jù),以五千條一次寫入的頻率,一百萬數(shù)據(jù)當(dāng)成一個(gè)批次。
var?flag?=?true;var?begin?=?0; var?tmpEnd?=?begin?+?5000; var?end?=?1000000;while?(flag) {//?省略讀取數(shù)據(jù)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); }為保證寫入的速度,先不要在那個(gè)臨時(shí)表建索引,等數(shù)據(jù)寫進(jìn)去后再給Id建索引。
把數(shù)據(jù)寫進(jìn)臨時(shí)表后,下面就是直接用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 --?這里更新要看數(shù)據(jù)庫的配置,如果配置高,可以一次更新,不然就建議25萬或50萬一個(gè)批次 --?where?a.id?>=?0?and?a.id?<=?500000--?查詢校驗(yàn)一下 SELECT?top?100?[id]?????,[IDCard]?????,[PhoneNo] FROM?dbo.yourtable?WITH?(NOLOCK) where?id?>?0?and?id?<=?500000? order?by?id?asc--?清除臨時(shí)表的數(shù)據(jù) truncate?table?dbo.enc_tmp--?刪除索引 drop?index?idx_enc_tmp_id?on?enc_tmp總結(jié)
設(shè)計(jì)系統(tǒng)的時(shí)候,數(shù)據(jù)安全還真的是不容小覷的,對(duì)一些敏感信息還是要加密入庫的。
修改數(shù)據(jù)的過程中,也涉及到了兩個(gè)知識(shí)點(diǎn),數(shù)據(jù)的批量插入和批量更新。
總結(jié)
以上是生活随笔為你收集整理的记一次批量处理数据库中的敏感信息的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: SwaggerUI看烦了,IGeekFa
- 下一篇: 十多位全球技术专家,为你献上近十个小时的