前言
本篇通过hash相关的应用引入怎样才能设计一个相对安全的账户系统。
使用场景
现在市面上有很多应用的账户系统的设计都存在安全上的问题,甚至不少app是直接将用户密码以明文方式直接发送至服务器做验证的,这样通过抓包分析很容易就可以知道用户的真实密码。那么怎么设计才能使用户的密码相对安全?这里来介绍hash在密码中的应用。
哈希的应用
- 用户密码的加密
- 版权验证
- 数字签名
- 搜索引擎关键字
用户密码的加密
常见的哈希算法: MD5 SHA1 SHA256 SHA512
常见加密方案:
- 直接使用MD5
- MD5加盐
- HMAC加密方案 下面我们通过对不同方案分析安全性:
直接使用MD5
该方法直接对明文密码做哈希,可以得到一个密文字符串,这样看来密码是得到了加密,但是如果明文密码过于简单也可以通过一个网站的海量数据库查找其密码的哈希值找到原密码。这里列出一个网站:www.cmd5.com
比如我们现在有一个密码明文: 594518655
查看其md5值是:5bd8dd4f65205c5eb4dc9ded5f7a0cb6
我们经过网站查找:
可以看出单经过md5的哈希得到的密码仍然是不够安全的
MD5加盐
我们在明文密码之上加一个固定字符串然后再进行md5的加密,这样会提高一定的安全性,cmd5网站也提供相应的加盐查找条件反推出密码,经过测试,盐过于简单确实可以拿到结果,盐越复杂安全程度越高,但是一旦这个固定的字符串被知晓也会变得不够安全。
HMAC加密方案
HMAC是密钥相关的哈希运算消息认证码,一种基于Hash函数和密钥进行消息认证的方法 使用一个加密用的key,做了两次散列。看下HMAC在登录系统中的使用:
注册流程
1.起初在用户注册账户时客户端会先将需要注册的用户名发送到服务器,服务器根据userName判断账户是否被注册过,然后会根据userName生成一个用于客户端做HMAC的key,这个key值和userName是一一对应的。
2.服务器将key值返回至客户端
3.客户端收到key值使用HMAC将用户的password散列成哈希值,连并用户名一同发送至服务器,服务器将userName,key,密码哈希值等信息存起来.
登录流程
-
客户端先将用户名发送至服务器验证该用户名是否存在,以及当前设备(设备唯一标识)是否有登录该账户的权限。
-
服务器判断用户名是否存在,设备是否有登录权限,如果都有,即把key,发送至客户端,客户端将key值和用户名捆绑保存到本地用于下次登录。
-
客户端用key值使用HMAC将用户的password加密成哈希值, 再加上一个从服务器时间同步的时间戳(精确到分钟),然后再次进行一次hash散列reuslt = hash(HMAC + timestamp) 将结果发送至服务器。
-
服务器拿到结果,取数据库中的HMAC+本地时间戳(容错1分钟,当前分钟可能不匹配,可能这个请求是x分59秒发的)进行Hash和客户端发送的数据比较,如果相同则登录成功
这样可以保证每次的登录请求数据只限制在一个时间段内有效提高了安全。
总结
使用HMAC加密用户密码这种方式保证了每次登录数据的动态性以及时效性的,加大了数据在网络传输时的安全性。