好用的 MS SQL 2005 欄位字串加密應用 ( MD5 與 SHA1 )

有人質疑為什麼密碼一定要加密呢??這個問題牽扯到資訊安全的環節了。請想想以下情況:

1.駭客入侵資料庫竊取資料
2.公司內部有心人士將資料庫內容偷偷竊取
3.網管人員偷偷使用主管級的帳密登入系統

 ***本文進階應用已刊登於 RUN!PC 2009 年 1 月號專欄***

 

部門最近決議,要將早期舊系統中使用者密碼的部分轉為加密字串,當然隨之而來的技術討論會議就開始了。
有人質疑為什麼密碼一定要加密呢??這個問題牽扯到資訊安全的環節了。請想想以下情況:

  • 駭客入侵資料庫竊取資料
  • 公司內部有心人士將資料庫內容偷偷竊取
  • 網管人員偷偷使用主管級的帳密登入系統

當一個公開的系統帳密完全外洩時,輕則系統下架不使用;重則公司或部門將面臨結束營業的情形 (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;

 產生以下的結果

MD5SHA1
0x827CCB0EEA8A706C4C34A16891F84E7B0x8CB2237D0679CA88DB6464EAC60DA96345513964


針對 HashBytes 的應用測試過程

接下來開一個測試用的 Table 來試試轉換的結果如何:

 

01 CREATE TABLE [dbo].[HashTest](
02 [INDEX_NO] [int] IDENTITY(1,1) NOT NULL,
03 [PassWD] [varchar](50) COLLATE Chinese_Taiwan_Stroke_CI_AS NOT NULL,
04 [HashedPW] [varchar](50) COLLATE Chinese_Taiwan_Stroke_CI_AS NULL,
05 CONSTRAINT [PK_HashTest] PRIMARY KEY CLUSTERED  
06 (
07 [INDEX_NO] ASC
08 )WITH (IGNORE_DUP_KEY = OFF) ON [PRIMARY]
09 ) ON [PRIMARY]
10 GO

 

 

在 PassWD 欄位中輸入一些字串, HashedPW 保持空白,等等要看加密的結果是否正確

INDEX_NOPassWDHashedPW
1test 
2test2 
3test3 

 

然後將以 SHA1 加密過的字串更新到 HashedPW 看看 --

update hashtest set hashedPW = HashBytes('SHA1', PassWD)

 咦??怎麼都變成亂碼了啊 O_o...這樣子根本不能用啊...再看了 MSDN 之後發現該函數的回傳值型態為 varbinary,並不是字串形態,所以要再使用 sys.fn_VarBinToHexStr() 進行轉換的動作 --

 

INDEX_NOPassWDHashedPW
1test咐戔 L s???閨
2test2
3test3>縛 鄀 o Y

 

update hashtest set hashedPW = sys.fn_VarBinToHexStr(HashBytes('SHA1', PassWD));

 

輸出的結果就正確了 :)

INDEX_NOPassWDHashedPW
1test0xa94a8fe5ccb19ba61c4c0873d391e987982fbbd3
2test20x109f4b3c50d7b0df729d299bc6f8e9ef9066971f
3test30x3ebfa301dc59196f18593c45e519287a23297589

 

最後...改一下登入機制的驗證方式,修改比對的欄位後...原本明碼的密碼就可以隨風而逝了,需求達成~