使用ajax+session+MD5安全登录

Posted by yuk on 2016-04-12

登陆安全性低

在做后台系统的过程中,尝试使用ajax发送post请求登录.用session记录状态.实际是可行的.
但使用Charles抓包工具抓包,却发现密码完全被暴露.

QQ账号登陆加密方法

出于好奇就粗略翻阅了一下源码:先从服务器请求到一个一次有效校验码,用户的密码加密之后和校验码还有其他一些信息一起再加密一次.发送给服务器。服务器应该是用这个校验码和用户密码做同样的加密运算,再比对。出于这个思路, 觉得可行。

具体实现

  1. 服务端渲染login页面,在session中生成一个verify_code,并渲染到登录表单。
  2. 用户输入username,password之后,提交表单前加密

    1
    2
    3
    4
    5
    import bcrypt from 'bcryptjs';
    import md5 from 'md5';
    ...
    password = bcrypt.hashSync(verify_code + md5(password), 10);
    #然后发送post
  3. 服务端校验,备注:数据库存的是MD5(password)结果

    1
    2
    bcrypt.compareSync( this.session.verify_code + 数据库中的密码暗文 ,
    params.password)

这样,就算被抓包,也只是拿到一个加密后的东西,而且verify_code随机且一次有效
最后 疑虑就是数据库里存的是MD5一次的加密结果,是否安全.可能可以md5两次.

参考的几段文字

但是如果在散列算法中加入了密钥,情况就不一样了。hmac 算法正好作了这样的事情,下面我们来看看如何用 hmac 算法实现安全登录。首先在客户端向服务器端请求登录页面时,服务器端生成一个随机字符串,连同登录页面一同发送给客户端浏览器,当用户输入完用户名密码后,将密码采用 MD5 或者 SHA1 来生成散列值作为密钥,服务器端发送来的随机字符串作为消息数据,进行 hmac 运算。然后将结果提交给服务器。之所以要对用户输入的密码进行散列后再作为密钥,而不是直接作为密钥,是为了保证密钥足够长,而又不会太长。服务器端接受到客户端提交的数据后,将保存在服务器端的随机字符串和用户密码进行相同的运算,然后进行比较,如果结果一致,则认为登录成功,否则登录失败。
—《安全登录系统的设计与实现方案》

另一篇文章

依据andot老师的文章,使用Javascript+PHP实现安全登录的最简便安全的方法就是服务器提供随机字串并将其存储,Javascript在客户端使用MD5将随机数和密码合并进行运算,将MD5过的字符串提交给服务器,服务器方也作相同的运算,与客户端提交的结果进行比对,就可以判断用户的身份了。这样,就算截获中途传输的数据,也只是一个MD5过的密码和一个一次性的随机字符串再次MD5运算的产物而已,随机字符串一旦使用过就会被立即销毁,无法再次验证,没有丝毫用处。而就算中途截获随机字符串,若不知道密码原文,依然无法向服务器递交合法的验证字符串。密码原文只在客户端浏览器上出现,不通过网络传输,每次提交的验证用的密码都不同,连服务器都不知道原文是什么,从而达到保护密码原文的目的。
—《用ajax做登陆时实现简单的加密》