关于登陆加密的一些疑惑

shiro里面预置了一些散列的加密算法,这些加密算法都是要逼近单向散列函数,简单的理解就是你可以通过输入的密码,然后放入哈希算法中去计算得到一串32位的字符串,然后持久化保存到数据库中,但是你没有办法把这个32位的字符串还原为密码,这个加密的过程是不可逆的。所以shiro这边在进行认证的时候,会在认证器Authenticator里写好加密的算法,用户认证的时候传入的token中有用户的密码,提取出来然后经过运算得到这串32位的字符串,去和数据库中的进行比较,如果一致就认证通过。这个操作避免了明文储存密码的隐患,数据库被入侵也不会导致用户的密码泄露。

因为一些简单密码的存在,所以通过md5的密文来反向推导出那些简单的密码也是可行的,这类网站也大量的存在。所以就有了盐这个概念,用户的密码加上盐然后再进行散列计算,这串密文被反向破解的几率就大大减小,每个用户都有自己的随机生成的盐,被保存在数据库中。这个操作是避免了数据库中简单密码被破解的隐患。

但是如果请求在中途被拦截,这时候用户的密码万一是明文传输,就被直接被拦住然后解析出来了,下次就直接拿着这个用户名和密码去登陆就行。所以要在客户端就进行加密,盐可以在前端就随机生成然后保存在session中,和密文一并传给server。服务器从session中获取盐,进行运算和比较,相同就通过认证。这个操作避免了请求被拦截后密码直接被取出的问题。(这个是我自己瞎想的,感觉逻辑有问题,这个session中的盐有什么用,数据库中要存的是密文,传过来的盐不是一点价值都没有,又不可能数据库里取出来然后解密再加密。所以应该是客户端传过来的的确应该是密文,但是收到以后要进行解密,变成用户输入的密码原文后再进行从数据库中读取盐,进行加密运算,然后再和数据库中保存的密文比较,相同就通过),所以客户端的盐是功能是,防止简单密码被拦截然后破解。

但是,如果是在用户点击登录按钮的瞬间,获取了password输入框里面的value值呢?他们不需要知道加密算法和盐是什么东西,他们只需要拿到用户的账号和密码就可以在下次直接登陆,那这个东西不是没办法去防范了,除非借助手机验证码这种可以证明身份的形式,或者是大数据进行分析,得出常用登陆电脑和登陆地点进行判断,不是常用的设备和地点就发验证码,是就可以登陆,不然没办法阻止他们获取用户名和密码啊。

是不是要换种思路,我理解的只有散列算法,太狭隘了?还是说道高一尺魔高一丈,是不可能完全阻止密码被获取的,动态的验证码也只能避免他们去成功登陆,并不能阻止他们获取正确的密码。

证书

update at 2016/09/27 14:10

需要一个签名(证书),而且一定要有时效性,时间戳是不可见的,随机数让他看到就看到,证书包括的是时间戳、密文、状态位。

首先传过来的肯定是要一个密文的形式,不能明文传输,需要加密后进行传输。

在用户请求登陆页面的时候,服务器同步生成一个签名,保存在服务器,并随着登陆页面返回过去,放在隐藏输入框中,签名的作用是判断用户请求的表单是不是服务器响应返回的那个,辨别被挟持伪造的请求,具有时效性。里面存着:时间戳(用户请求登陆的时间),状态位(判断是否被劫持伪造过),随机生成的密文,作为判断。

用户接收到登陆页面开始登陆,输入用户名、密码,点击登陆按钮开始登陆,此时对明文密码进行加密然后进行传输。此时签名也作为隐藏的输入域被提交, 状态位此时被修改,(状态位不应该这么使用,这样被拦截了也没什么用啊),同时提交的还有当前的时间戳。

服务端接收到用户登录的信息后,首先要去进行签名的对照,两个时间之间的间隔是否超时,若超时则判断此登陆无效;此外判断签名中的密文是否一致,状态位是否正确,如果通过,就进入密码核对环节。

数据库进行散列存储是为了避免内部运维看到明文密码,或者数据库泄露被拖库后导致用户信息流出。这一步在注册的时候即完成,随机生成一个盐,保存在用户的身份信息表中,不可逆的散列算法计算多次后保存密码。

再加上判断是不是常用地点、常用设备登陆,不是就加上一个手机短信验证码的程序,来判断是不是本人在使用。

不可能做到绝对的安全。