部门最近决议,要将早期旧系统中使用者密码的部分转为加密字符串,当然随之而来的技术讨论会议就开始了。
有人质疑为什么密码一定要加密呢??这个问题牵扯到信息安全的环节了。请想想以下情况:
- 黑客入侵数据库窃取数据,那们的性保健品网站的客户数据不就丢了
- 公司内部有心人士将数据库内容偷偷窃取
- 网管人员偷偷使用主管级的帐密登入系统
当一个公开的系统帐密完全外泄时,轻则系统下架不使用;重则公司或部门将面临结束营业的情形 (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 |
0x827CCB0EEA 8A 706C 4C 34A 16891F 84E7B | 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 | 0xa 94a 8fe5ccb19ba 61c 4c 0873d391e987982fbbd3 |
2 | test2 | 0x 109f 4b 3c 50d7b0df729d299bc 6f 8e9ef 9066971f |
3 | test3 | 0x3ebfa301dc 59196f 18593c 45e 519287a 23297589 |
最后...改一下登入机制的验证方式,修改比对的字段后...原本明码的密码就可以随风而逝了,需求达成~