服务端数据库有 LoginSalt 和 PasswordSalt 两个字段,前者是变化的,后者是固定的。 首先服务端存放的密码是 MD5(p + PasswordSalt) (p 为明文密码), PasswordSalt 是针对每个用户单独生成的,用来防彩虹表。
1.注册的时候
客户端生成 PasswordSalt 然后把 MD5(p + PasswordSalt) (这里用 PasswordSalt 是为了防止截取注册密码用彩虹表反推)和 PasswordSalt 传递给服务端,如果注册成功,服务端保存这两者
2.登录的时候
首先向服务端请求 LoginSalt ( LoginSalt 在请求时生成,并存入对应的用户中)和 PasswordSalt ,然后向服务端发送 MD5(MD5(p + PasswordSalt) + LoginSalt),然后服务端进行验证,如果验证通过,即登录成功,将重新生成 LoginSalt 并存入对应用户(防止重放攻击),这时候同时向客户端返回这个 LoginSalt ,以作为权限高一级 API 的 Token 。
这样是否可行?主要想达到的目的有三个, 1 是防彩虹表, 2 是防止重放攻击, 3 是给高权限 API 一个凭证 仔细想了下,或许还得有个 Token 字段,登录成功后返回随机生成的 Token 来代替 LoginSalt 比较好,直接用 LoginSalt ,别人用你的账号请求一次,你的 LoginSalt 就变了,请求高权限 API 就无效了
1
armoni 2016-04-29 10:21:51 +08:00 1
想太多了, loginsalt 没必要, API 请求权限请另外做处理,不要和账户绑定
|
2
mlkr 2016-04-29 11:55:53 +08:00
ssl
|
4
armoni 2016-04-29 18:10:46 +08:00
@mhsj6621 1.如果是 b/s 架构,可以用验证码或者三次失败后输入验证码来拦截攻击 移动端服务架构思路也是类似,多次登录失败后拦截请求
2.API 的权限和整个系统业务的权限管理关联起来, spring security 之类。 如有其它做法,欢迎讨论 |
5
SmiteChow 2016-04-29 21:59:19 +08:00
不用这么复杂
|
7
mhsj6621 OP @armoni 用验证码的话只是防止别人穷举,但是防不了重放啊。。
还有 API 的权限的话,粒度比较粗,只是为了区分登陆和未登陆.. |
8
armoni 2016-04-30 09:10:28 +08:00
https 就解决了
|