作者StubbornLin (Victor)
看板C_and_CPP
标题Re: [问题] 请问一般程式是用什麽方式储存个资呢?
时间Tue Jan 11 14:31:13 2011
※ 引述《QQ29 (我爱阿蓉)》之铭言:
: 请教各位
: 一只程式如果要储存使用者的个人资料 一般都用什麽方式储存呢
: 假如要储存使用者密码
: 我自己是觉得不可能完全不处理就直接写成text 或是 binary
: 是怕说有人可以窃取到密码
: 但是我不晓得一般有什麽common approach 去处理这块
: 加密我也不懂
: 但真的要用加密吗?
: 还是就存成binary就好.....
: 谢谢
密码通常都是存hash之後的值,但是hash有很多种方法,比较简单的就是直接hash
hash(password)
但是这有个缺点,如果密码取得很短很烂
透过事先建好的字典档就能快速找到对应的密码,举个例子
用md5当hash函数
密码为 "1234" 对应md5为 81dc9bdb52d04dc20036dbd8313ed055
攻击者只要拿网路上已经建好的md5资料库查询就有了
事先建好的资料库会像这样
...
"1232" -> e53a0a2978c28872a4505bdb51db06dc
"1233" -> e034fb6b66aacc1d48f445ddfb08da98
"1234" -> 81dc9bdb52d04dc20036dbd8313ed055
"1235" -> 9996535e07258a7bbfd8b132435c5962
...
随便找个线上md5资料库,像是这个
http://md5online.net/
输入 81dc9bdb52d04dc20036dbd8313ed055
很快就能找到对应的原始密码,为了避免这些密码直接被拿来这类的资料库中找对应值
可以加一个salt,也就是一串乱数进去
可以存
hash(password || salt) + salt
salt这边是随机产生一的段乱数,可以产生几个乱数喂给一个hash来产生
我们来看一下例子
salt = "97ae97fa15493d04d06e38822b096b88"
password = "1234"
md5(password || salt) 结果是 74d8abb9518b81f14e13c2835778d50a
在资料库里就不会被找到
"74d8abb9518b81f14e13c2835778d50a not found in our database."
而验证的方法很简单,就从资料库里拿出
hash(password || salt) || salt
因为hash结果长度是固定的,取出salt来和使用者输入的密码 password' 做hash
hash(password' || slat) == hash(password || salt)
一样就表示正确
好吧,虽然1234这种烂密码透过暴力法展开所有组合去猜
hash(? || salt) == hash(password || salt)
问号的地方代入所有组合就可以猜到,这时候就得依赖密码本身的强度
因此在让使用者输入密码时尽量提升强度的可能性
不能和id, email等等一样,长度要到n位以上,至少要有符号之类的
这样就比较安全一点,至於被猜到的机会有多少,有一种模型叫
random oracle是专门用来评估这类hash里夹密秘值被猜到的机会有多少
(中文要怎样翻? 随机神谕? 听起来好酷 XD)
这东西我就不懂了 XD 不好懂
但就这样做对大部份的网站存密码而言应该就已经够安全
当然,安全还得看你存的是什麽资料而定
如果存的是核弹启动的密码这就不够安全了
我个人对安全的定义是破解它的成本远大於资料本身的价值
破解成本 >> 资料价值
参考看看
--
Now.in 网路广播电台平台
http://now.in
易记学 程式设计教学
http://ez2learn.com/
VICTOR's 个人Blog
http://blog.ez2learn.com/
--
※ 发信站: 批踢踢实业坊(ptt.cc)
◆ From: 111.252.66.27
※ chmod:转录至看板 NetSecurity 01/11 14:57
1F:推 bdvstg:是 '|' 还是 '||' ? 01/11 15:47
2F:推 ducksteven:|| 是指 concatenate 吧? 01/11 16:07
3F:推 freehand1122:原po的意思应该是字串连接 01/11 18:29
4F:推 bdvstg:喔喔~~ 我还以为是要做位元操作XD 01/11 18:45