密码存储与传输的那些事儿(五)密码传输

       对于密码的存储,需要使用密码哈希来保证用户隐私与密码安全,对于这一点基本上是没什么争议的。但对于像用户登陆这样的场景来说,需要传递用户密码,这时是否需要使用哈希算法?如何保证密码安全?


首选HTTPS

  • HTTPS肯定是最安全的方式,这点是毋庸置疑的。有些人也很极端的说,“如果项目都不肯用HTTPS,这样的公司待下去也没啥意思”,这点我却不敢苟同了。实际上很多小项目或者是私活之类的事儿,你也很难希望人家会有额外的资金给你用于申请证书,然而作为一位有节操的码农,你肯定还是希望保护一下用户的密码。
  • 至于在HTTPS下是否需要给密码哈希,这个就见仁见智了。使用HTTPS,密码传输安全实际上已经保证了,但对于一些监管不是很严格的公司,难保开发维护人员会在后台给你加上啥东西,没准直接就把用户密码打印到日志输出了,不少公司对代码管理其实都不是很严格,也难保程序员离职前给你搞一波什么事儿。另外,我还是觉得0.1并不等于0,做了保护总比明文要强一些,为此个人还是倾向于需要进行前台哈希。
  • 对于APP端的接口开发,个人感觉没啥好说的,直接上HTTPS吧,哪怕你可以自己签发证书,只要在客户端上安装信任自己的根证书即可。

HTTP情况下的密码保护

方法一

  • 服务器端存储密码为Hash(Random-Salt + Hash(Constant-SALT + Pasword))
  • 客户端传输密码为Hash(Constant-SALT + Password)
  • Random-Salt为用户的随机盐,每个用户均不同,服务器端收到客户端的hash密码后,在将其与用户随机盐一起Hash运算,从而将结果与数据库存储值相比较。
  1. 优点:数据库存储的密码经过两层哈希,且其中包含了固定盐和用户随机盐,安全性较高
  2. 缺点:客户端传输的密码虽然经过了一层哈希,但是使用固定盐值,因此相同密码生成的结果均一致,容易收到重放攻击

方法二

  • 服务器端存储密码为Hash(Constant-SALT + Pasword)
  • 客户端传输密码为Hash(Random-Salt + Hash(Constant-SALT + Password))
  • Random-Salt为每次进入登陆页面时生成的随机盐,此处主要是为了防止重放攻击,作用类似与nonce
  • 服务器收到客户端上传的hash之后的密码,根据用户ID取出服务器存储的密码,并通过与之前返回客户端的Random-Salt(可存储于Session中)进行Hash运算,从而与客户端上传的密码进行比较。
  1. 优点:客户端有效的防止了重放攻击
  2. 缺点:在前端代码中,固定盐值暴露,一旦后台数据库被攻破,用户密码信息将有危险。

综合比较

     在HTTP的情况下,个人建议还是使用方法二较为合适,传输时的安全是HTTP的痛点。至于后台密码存储的安全,可使用BCrypt或SCrypt进行保证,将计算迭代次数调高,增加计算时间,从而防止彩虹表与字典攻击。

      对于HTTPS的情况,如果同时希望将密码哈希后进行传输,则个人建议使用方法一。

      至于Hash算法的选择,上述均涉及两层Hash算法,首先对于服务器端密码存储时,个人建议还是要使用BCrypt算法。而对于客户端密码传输时的Hash,可选用SHA256或者是将BCrypt算法的迭代次数调低一点,加快计算速度。总的来说,还是要控制完整的登陆哈希时间不要超过300ms。

你可能感兴趣的:(安全)