前言:
在JavaWeb日常实践中,注册功能是必不可少的,但一直用明文的方式去将密码持久化进数据库是非常不安全的,因此我找到了解决方法,那就是加密。
而目前常见的就是md5加密,在以往的那些年md5加密确实非常实用,但依旧有破解的方法(有人说md5加密是不可逆的怎么可能破解),答案就是海量数据的抓取的匹配,让md5有变得不那么安全,因此,盐值md5加密出现了,下面就给大家说说什么是salt,以及在做安全认证时经常碰到的token是什么东西
一,什么是salt
所谓加Salt,就是加点“佐料”。当用户首次提供密码时(通常是注册时),由系统自动往这个密码里加一些“Salt值”,这个值是由系统随机生成的,并且只有系统知道。然后再散列。而当用户登录时,系统为用户提供的代码撒上同样的“Salt值”,然后散列,再比较散列值,已确定密码是否正确。
这样,即便两个用户使用了同一个密码,由于系统为它们生成的salt值不同,他们的散列值也是不同的。即便黑客可以通过自己的密码和自己生成的散列值来找具有特定密码的用户,但这个几率太小了(密码和salt值都得和黑客使用的一样才行)。
假设你的数据库已经被黑客拿到了。 比如 md5sum("123456") = "e10adc3949ba59abbe56e057f20f883e" 如果不用 salt ,直接 md5 的话,直接在你的数据库里搜索后面那个值不就能找出所有密码是"123456"的用户了吗? 要知道,黑客的目的其实并不是(或者说大多数时候不是)破解某一个人的密码,而是获取大量的用户名/密码对。 好了,现在你加了盐,但盐是固定的,比如直接写死在代码里的,这样行不行呢?这样也是不行的,因为黑客仍然可以通过预先计算的方式来做。比如黑客黑了你的服务器,看到了你的代码,知道了你的盐是 xxx ,于是他计算: md5sum("123456xxx") = "e087dae60e744ea80722b785a75adbb7" 然后再到你的数据库里搜索,又能得到大量密码是 123456 的用户了。 那该怎么办呢? 所以,不但要加盐,而且每个用户的盐还得不一样。我看到的一种做法是,直接用每个用户的用户名,或者用户名的变形来做盐。
二,Token的作用
Token,就是令牌,最大的特点就是随机性,不可预测。一般黑客或软件无法猜测出来。
那么,Token有什么作用?又是什么原理呢?
Token一般用在两个地方:
-
1)防止表单重复提交、
-
2)anti csrf攻击(跨站点请求伪造)。
两者在原理上都是通过session token来实现的。当客户端请求页面时,服务器会生成一个随机数Token,并且将Token放置到session当中,然后将Token发给客户端(一般通过构造hidden表单)。下次客户端提交请求时,Token会随着表单一起提交到服务器端。
然后,如果应用于“anti csrf攻击”,则服务器端会对Token值进行验证,判断是否和session中的Token值相等,若相等,则可以证明请求有效,不是伪造的。
不过,如果应用于“防止表单重复提交”,服务器端第一次验证相同过后,会将session中的Token值更新下,若用户重复提交,第二次的验证判断将失败,因为用户提交的表单中的Token没变,但服务器端session中Token已经改变了。
上面的session应用相对安全,但也叫繁琐,同时当多页面多请求时,必须采用多Token同时生成的方法,这样占用更多资源,执行效率会降低。因此,也可用cookie存储验证信息的方法来代替session Token。比如,应对“重复提交”时,当第一次提交后便把已经提交的信息写到cookie中,当第二次提交时,由于cookie已经有提交记录,因此第二次提交会失败。
不过,cookie存储有个致命弱点,如果cookie被劫持(xss攻击很容易得到用户cookie),那么又一次gameover。黑客将直接实现csrf攻击。
所以,安全和高效相对的。具体问题具体对待吧。