写在前面的文章中描述了我对如何在数据库中保存密码的理解。从最简单的明文存储到密码加盐存储,分享给大家:第一阶段刚接触web开发的时候,user表的密码基本都是明文存储的,比如:username|password--------|----------zp1996|123456zpy|123456789这种方式可以说是非常不安全的。一旦数据库泄露,所有用户信息都将被泄露。之前这种方式在国内被广泛使用,造成了很多事故,比如csdn600万用户信息泄露,12306用户信息泄露等。第二阶段,我大学做的项目基本都是用这种方式保存用户密码,即用md5加密密码,只需要在php中使用md5,在??node中使用crypto模块:constencrypt=(text)=>{returncrypto.createHash("md5").update(String(文本))。摘要(“十六进制”);};作为初学者,我觉得这个方法是很安全的,因为md5是不可逆的(意思是攻击者不能从hash值h(x)推导出x)和低碰撞概率(意思是攻击值找不到两个值x,x'具有相同的哈希值);不过,这种方法并不安全,只要把常用的密码都枚举出来,做个索引表,就可以推导出原来的密码了。这个索引表也叫“彩虹表”(之前csdn的600万用户的明文密码就是个好素材)。第三阶段,在实践中学习这个方法,即给密码加盐。什么是盐?在密码学中,是指在密码的任意固定位置插入特定的字符串,使哈希后的结果与使用原密码哈希后的结果不一致。这个过程称为“腌制”。加盐很容易理解。就是在原来的密码上加了一个特定的字符串,增加了攻击者的攻击成本。加salt的关键在于如何选择salt:fixedstring使用固定字符串作为salt,如下:constencrypt=(text)=>{text=text+'zp';返回crypto.createHash("md5").update(text).digest("hex");};和md5一样,没有任何意义,攻击者能拿到数据库,难道就不能拿到源码吗,根据源码,攻击者可以轻松构造新的彩虹表并逆向密码.随机串salt一般要求是固定长度的随机串,每个用户的salt不一样,比如10个字符。数据库可以这样存储:username|密码|盐----------|----------------------------------|---------zp1996|2636fd8789595482abf3423833901f6e|63UrCwJhTHzpy|659ec972c3ed72d04fac7a2147b5827b|84GljVnhDT采用的加密方式为:md5(md5(password)+salt)转化为节点编码:/**10位salt*timestamp(2)+randomletters(8)*/constsalt=()=>{vartime=Date.now()%100,str='';时间=时间===0?'00':字符串(时间);for(leti=0;i<8;i++){constbase=Math.random()<0.5?65:97;str+=String.fromCharCode(base+Math.floor(Math.random()*26));}返回时间+str;};constmd5=(text)=>{returncrypto.createHash("md5").update(String(text)).digest("hex");};constencrypt=(password)=>{returnmd5(md5(password)+salt());};写在最后,用随机字符串给密码加salt,因为salt只是为了增加破解难度密码。如果当前有30万条用户数据,那么就有30万盐,用600w的索引表比较if,一对一对比需要创建30w*600w的数据,会增加攻击者的成本。如有错误,请指出。
