部門最近決議,要將早期舊系統中使用者密碼的部分轉為加密字串,當然隨之而來的技術討論會議就開始了。
有人質疑為什麼密碼一定要加密呢??這個問題牽扯到資訊安全的環節了。請想想以下情況:
有人質疑為什麼密碼一定要加密呢??這個問題牽扯到資訊安全的環節了。請想想以下情況:
- 駭客入侵資料庫竊取資料
- 公司內部有心人士將資料庫內容偷偷竊取
- 網管人員偷偷使用主管級的帳密登入系統
當一個公開的系統帳密完全外洩時,輕則系統下架不使用;重則公司或部門將面臨結束營業的情形 (TigerLin 朋友的公司曾經發生過,想當然爾…結束營業)。這就是一直強調密碼要編碼過的原因所在了。
在找了 MSDN 相關文件之後發現…其實 SQL 2005 就有內建的函式可直接應用了,而且很方便的呢。不過…中間也是發生了一點插曲,折騰了一下才試出來 ^~^a …
MS SQL 2005 字串加密函式 — HashBytes
HashBytes提供的加密法有幾種 (MD2、MD4、MD5、SHA、SHA1 ),但最常使用的還是 MD5 與 SHA1。而整個使用過程的感覺來說,基本上還算簡單~只是有一些”眉角”要注意。首先先測試 HashBytes 運作是否合乎需求:
1 | select hashbytes(‘MD5’,‘12345’) as MD5,hashbytes(‘SHA1’,‘12345’) as SHA1; |
產生以下的結果
MD5 | SHA1 |
0x827CCB0EEA8A706C4C34A16891F84E7B | 0x8CB2237D0679CA88DB6464EAC60DA96345513964 |
針對 HashBytes 的應用測試過程
接下來開一個測試用的 Table 來試試轉換的結果如何:
1 | CREATE TABLE [dbo].[HashTest]( |
2 | [INDEX_NO] [int] IDENTITY(1,1) NOT NULL, |
3 | [PassWD] [varchar](50) COLLATE Chinese_Taiwan_Stroke_CI_AS NOT NULL, |
4 | [HashedPW] [varchar](50) COLLATE Chinese_Taiwan_Stroke_CI_AS NULL, |
5 | CONSTRAINT [PK_HashTest] PRIMARY KEY CLUSTERED |
6 | ( |
7 | [INDEX_NO] ASC |
8 | )WITH (IGNORE_DUP_KEY = OFF) ON [PRIMARY] |
9 | ) ON [PRIMARY] |
10 | GO |
在 PassWD 欄位中輸入一些字串, HashedPW 保持空白,等等要看加密的結果是否正確
INDEX_NO | PassWD | HashedPW |
1 | test | |
2 | test2 | |
3 | test3 |
然後將以 SHA1 加密過的字串更新到 HashedPW 看看 —
1 | update hashtest set hashedPW = HashBytes(‘SHA1’, PassWD) |
咦??怎麼都變成亂碼了啊 O_o…這樣子根本不能用啊…再看了 MSDN 之後發現該函數的回傳值型態為 varbinary,並不是字串形態,所以要再使用 sys.fn_VarBinToHexStr() 進行轉換的動作 —
INDEX_NO | PassWD | HashedPW |
1 | test | 咐戔 L s???閨 |
2 | test2 | |
3 | test3 | >縛 鄀 o Y |
1 | update hashtest set hashedPW = sys.fn_VarBinToHexStr(HashBytes(‘SHA1’, PassWD)); |
輸出的結果就正確了 🙂
INDEX_NO | PassWD | HashedPW |
1 | test | 0xa94a8fe5ccb19ba61c4c0873d391e987982fbbd3 |
2 | test2 | 0x109f4b3c50d7b0df729d299bc6f8e9ef9066971f |
3 | test3 | 0x3ebfa301dc59196f18593c45e519287a23297589 |
最後…改一下登入機制的驗證方式,修改比對的欄位後…原本明碼的密碼就可以隨風而逝了,需求達成~