首先要知道服务器不会保存用户的真实密码!!!服务器也不知道用户的密码是多少(本文用MD5进行加密)
1. 注册登录
1.1 发送账户及密码给服务器端进行注册。在发送之前需对密码进行MD5进行加密。
ps:这样直接加密传输会有一个问题,如果捕获到加密后的字符串,可在
https://www.cmd5.com 网站可进行查询,不安全
1.2 加盐优化处理。直接加密不安全,则需加盐,首先定义一个盐 salt = kf
iclx~a^
切盐要足够复杂,足够长,然后在原始密码的基础上拼接该salt字符串后再对其进行MD5。
ps:虽然这样相对安全。但所有数据加密都依赖该salt,一旦盐泄露,
则数据非常不安全,并且可能用户很多app都是一个密码,可能造成的后果更严重。
并且如果重新更换改盐,可能之前注册的用户登录不上,造成用户流失。
1.3 HMAC加密方案(底层还是hash)
HMAC使用一个秘钥进行加密,并且做了两次散列。在实际开发中是来在于服务器的
pwd = [pwd hmacMD5StringWithKey:@"key"] //实际开发中key是来自于服务器的
HMAC加密流程简单示意图.jpg
- 用户A在设备A1先进行登录时(未注册)。输入用户名密码。点击登录后,客户端首先发送用户名给服务器
- 服务器根据账号生成相应的key保存在服务器端。并同时返回给客户端。
- 客户端接收到key时。使用HMAC进行加密,生成HMAC密码,并同时把用户名及HMAC密码发送给服务器端进行验证。同时保存key在本机中
ps: 此时服务器及客户端分别保存的有
服务器端:用户名 、 key 及 HMAC密码
客户端: 用户名 、 key
再次登录时,直接用本机保存的key直接加密进行登录
如果用户A更换设备时:
- 用户A在设备A2进行登录时。输入用户名密码。点击登录后,客户端首先发送用户名给服务器
- 服务器根据账号查询到保存在服务器端对应的key。返回给客户端。
- 客户端接收到key时。使用HMAC进行加密,生成HMAC密码,并同时把用户名及HMAC密码发送给服务器端进行验证。验证成功后。把key保存在本机中
--- 对比MD5加盐,盐针对整个项目的。key是针对某个账户的 ---
使用HMAC也可实现设备锁功能。key只返回给开通了设备锁的设备,其他设备不返回。
2. 优化(密码有效期)
不管对于MD5加盐还是HMAC都可以通过请求拦截,模拟客户端发送请求。
例如:某个app新用户注册可以领礼品。下载app时。你连了他们提供的wifi,此时你手机上所有的请求都可以被拦截。当然包括你注册登录密码。这时候就可以模拟你的客户端给服务器发送请求,但此时你的真实密码他是不知道的。
优化方案:需要每次登录时密码都不一样(除第一次注册外之后的登录)
- 客户端在验证时:在发送HMAC密码时,在后面拼接时间token: 202006281335(直到分钟)
( HMAC密码 + 202006281335 )MD5 - 服务器将用户名及MD5后的32位密码发送给服务器。
- 服务器是保存有原始的HMAC密码的。通过用户名关联到对应的HMAC密码,然后拼接本机时间后MD5,再与客户端发过来的字符串比较
第一次:( HMAC密码 + 202006281335 )MD5
第二次:( HMAC密码 + 202006281334 )MD5
如果第一次比较失败。则比较前一分钟,这样密码最短有效期60s,最长有效期120s
这样即便数据被截获,也只能在两分钟进行登录。否则该密码就失效了。
实际项目中,所有的时间尽量取服务器时间。不要取本机时间。
另外:
场景一:搜索引擎
搜索内容 为: 【中国 上海 浦东】 或者 【浦东 上海 中国】时搜索到的内容大致是一直的。
在批对时。搜索引擎会分别对搜索内容进行MD5生成32位字符
假设加密后字符为:
中国 11111111111 浦东 33333333333
上海 22222222222 上海 22222222222
浦东 33333333333 中国 11111111111
然后在对其分别进行位运算:不论先后顺序。结果都为:66666666666
场景二:百度云
百度云盘上的视频,有时候会被和谐。其实记录的不是电影名字。而是对电影源文件数据进行MD5后的32位字符串。这样不管电影名字如何改。只要视频资源不变,MD5后的字符串都一样。













网友评论