如何正确的进行密码保护?

时间:2024-03-30 14:42:04

前言

密码加密很重要,如果泄露是后台管理员的用户密码,会严重的损害系统的安全性;如果密码不加密直接明文存储到数据库,一旦数据库泄露,密码也会泄露,而大部分人在不同网站上用的密码都是一样的,黑客拿到密码便可以攻击该用户的别的网站的账号(据说之前csdn就报出密码明文存储的事情)。

密码加密很重要,但是很多人忽视了。用户的密码设置过于简单、程序员在开发时未考虑密码的加密。这一切都导致做出来的web系统让黑客进出自如。

这篇文章试图从多个角度去探讨,作为程序员,我们应该如何处理好密码,如何更好的对密码进行加密。

1、源头上遏制弱口令

众所周知,网络上常常有弱口令密码表,黑客只需要遍历弱口令表去试探密码,就可以完成这一暴力**过程。
因此一个好的方式是,从源头上拒绝弱口令的出现:

  1. 密码的长度应该达到8位以上
  2. 密码应该同时由数字、字母和其他字符组成
  3. 密码和用户名不应该存在联系
  4. 密码不应该和上一次设置的密码相似(重置密码时)
  5. 定时,如半年进行密码的修改
  6. 应该有确认密码机制,防止密码过于复杂,用户误输入
  7. 用户名要有最短长度限制,用户名不应该可以其他用户重名

如何进行验证?

  • 前端进行验证,验证密码和确认密码一致、验证密码长度、复杂度符合要求,同时和用户名不存在强的关联(可以用KMP算法)
  • 后端需要将前端验证的那几项再验证一次,因为前端的数据往往是不可信任的,通过一些方式可以很轻松的绕过前端的验证
  • 后端接着校验密码和上一次设置的密码不相似

2、主动防御

我的理解是:给密码加密属于被动防御,它并没有阻止黑客进行攻击,只是增加了攻击的复杂度而已。
而主动防御则是限制用户只能从前端界面进行登录(一定程度上限制了黑客使用脚本),从而提高了密码被**的难度。

  • 设置密码输入错误达到一定次数锁定账户
    • 这种方式能有效的应对黑客的暴力解密
  • 设置前置登录条件
    • 前置登录条件指的是在登录之前必须要做一些事,才能进行登录:
    1. 比如说需要绘制手势密码
    2. 比如说要按一定顺序点击页面某些特定的地方后(这里可以在点击某些特定的地方时发送特定的请求),后端将这些点击的顺序存入缓存,满足一定顺序和正确性条件后才允许请求登录接口),这种很适合用在一些私人性质很强的系统中。保密性也不错,毕竟很少人能想到在登录之前必须要点击某些地方。
    3. 比如说需要从一系列图片中选择出正确图片
  • 设置登录锁定IP,如果要在另一个IP登录,则需要进行手机或者邮箱验证码验证
  • 直接设定每次登录都要进行手机或者邮箱验证码验证

3、简单的办法来保证密码传输时的安全性——使用HTTPS

如何正确的进行密码保护?
如何正确的进行密码保护?

客户端在使用HTTPS方式与Web服务器通信时有以下几个步骤,如图所示。

(1)客户使用https的URL访问Web服务器,要求与Web服务器建立SSL连接。

(2)Web服务器收到客户端请求后,会将网站的证书信息(证书中包含公钥)传送一份给客户端。

(3)客户端的浏览器与Web服务器开始协商SSL连接的安全等级,也就是信息加密的等级。

(4)客户端的浏览器根据双方同意的安全等级,建立会话**,然后利用网站的公钥将会话**加密,并传送给网站。

(5)Web服务器利用自己的私钥解密出会话**。

(6)Web服务器利用会话**加密与客户端之间的通信。

因此,使用了SSL之后,信息在传输时便已经进行了加密,明文密码在传输时也得到了加密。
很多人没有意识到有这么一个简单的方式来进行密码传输时加密。这比自己实现的简单加密安全性要高。

4、一个简单的密码验证思路

如果1、2、3步骤都做了,那哪怕密码使用明文传输,安全性也不会低了。

对于很多系统并不要求达到很高的安全性(应该基于系统和数据的重要性去研究是否使用复杂的加密手段),我们可以基于HMAC这种**哈希算法,就可以提高很多的安全性:

  • 前端密码加密:
    1. 前端请求登录,后端回复一个随机字符串,并存在session中
    2. 前端使用HMAC(密码明文 + 随机字符串)=》密码密文,发给后端
  • 后端密码加密:
    1. 后端从数据库取出AES密码密文
    2. AES解密获得密码明文
    3. HMAC(密码明文 + 随机字符串)=》密码密文
    4. 和前端的密文对比,正确则登录成功

5、结合验证码进行复杂加密

现在几乎所有的网站、APP都有使用登录验证码。但不是都用来进行加密。
登录验证码的主要用途:

  1. 防止机器人、爬虫。(多见一些图片验证码、拖曳人机验证)
  2. 用户身份验证,同时增加注册成本。(手机验证码、邮箱验证码)
  3. 保证登录的时效性。(一般登录验证码都有时效)
  4. 结合密码进行加密

基于验证码,我们能够得到一种较安全的加密思路:

  • 前端注册加密规则

    1. 从后端获取RSA公钥
    2. 生成一个随机的AES**
    3. RSA加密(AES**,RSA公钥)=》AES**密文、
    4. AES加密(密码明文 + 验证码, AES**)=》密码密文
    5. 将AES**密文和密码密文发给后端
  • 后端注册获取密码

    1. RSA解密(前端传的加***,RSA私钥)=》 AES**、
    2. AES解密(密码密文, AES**)=》密码明文 + 验证码
    3. 对密码明文进行验证,如长度、数字字母要求等
    4. SHA256加密(密码明文)=》密码密文 (如果需要保存明文,可以不要这一步)
    5. AES加密(密码密文,后端存储的AES**)=》二重密文
    6. 二重密文 =》 数据库
  • 前端登录加密规则

    1. SHA256(SHA256(用户名 + SHA256(密码)) + 验证码)三重hash加密
  • 后端登录验证加密规则

    1. 从数据库取出二次加密密码密文,即:AES加密(密码密文,后端存储的AES**)
    2. 解密得到密码密文,AES解密(密码密文,二次加密密码密文)=》密码密文,即SHA256(密码明文)
    3. 从缓存读取验证码,如果过期则返回验证码已过期
    4. SHA256(SHA256(用户名 + 密码密文) + 验证码)=》模拟前端进行加密
    5. 将加密的结果和前端传过来的密码进行对比
    6. 对比成功,返回登录成功,反之登录失败
  • 为什么要进行前端加密?

  • 简单说就是前端到后端的这段过程密码很可能被拦截。

  • 为什么前端加密要多重加密,并用验证码加盐?

  • 多重加密使得密码更加复杂,同时能糅合用户的用户名信息,提高唯一性、糅合验证码,提高时效性。

  • 为什么前端注册要用RSA进行非对称加密?

  • 因为不管怎么对前端的密码进行加密,都可能被拦截,从而获取到密码或者密码密文。黑客利用这个密码或者密码密文就可以模拟前端进行登录(越过前端的加密,直接发密文)。而用了RSA之后,配合随机生成的AES**,黑客得不到RSA私钥,几乎无法**得到密码的明文。

  • 为什么密码存到数据库之后还要进行哈希加密,然后进行AES加密?

  • 这只是最后一道手段,因为假设黑客已经黑入了数据库(通过sql注入或者别的什么方式),此时所有的密码都会在他的眼前,他可以通过这些密码,达到登录的目的。而如果再加一层AES加密,并将AES**存储在文件中而不是数据库中,黑客几乎无法利用这些密码。别提解析明文,连用来登录此系统都有难度。

  • 密码验证通过之后就无忧了吗?

  • 错,基于跨域攻击获取cookie的方式,或者拦截获取token的方式,黑客仍然可以伪造用户已登录的状态。通过文件上传漏洞,黑客可以运行脚本,控制服务器。通过xss攻击进行js注入,可以将用户的信息发到自己的网站。因此,web安全永远是木桶效应——你能达到的安全性取决于你的短板,而不是你做的最好的那个方面。

  • 为什么登录中不用RSA加密?

  • RSA加密解密速度较慢,如果系统用户不多,或者登录的响应速度不是最重要的点,就可以考虑每次登录都用RSA进行加密。

参考&引用

为什么HTTPS比HTTP安全,以及两者的优缺点
https://www.cnblogs.com/zhangsanfeng/p/9125732.html