基于两次RSA加密动态Token解决方案

非对称加密的Token解决方案

1:在登录页客户端向服务端发出getSPK请求,传递did,由客户端生成,web使用指纹id,app使用设备id

2:服务端收到后,使用RSA算法生成一对密匙,长度是1024位,服务端公匙SPK和服务端私匙SSK。 同时生成服务端10位时间戳一起发给客户端; 把SSK保留在服务端,以did为key,SSK做为值存储在redis的set中,过期时间为10分钟

发送验证码

3:客户端把SPK存入本地(如果本地有就更新),客户端使用RSA算法生成密钥(客户端公匙CPK和客户端私匙CSK)把CSK保存本地变量中

4:构造签名:把(设备id,手机号,服务端时间戳)进行字符串拼接后按字母排序,再使用sha1算法得到签名sign

5:数据加密:把(手机号,时间戳,sign)进行字符串拼接后按字母排序,再使用SPK进行加密,得到加密data,连同CPK,did一起发送给服务端

6:服务端收到data后,用did查询到私匙SSK进行解密;得到客户端sign,手机号,时间戳。然后用服务器时间和解密出来的时间戳比较,差值大于10分钟,返回错

7:把(设备id,手机号,服务端时间戳)进行字符串拼接后按字母排序,再使用sha1算法得到签名sign-1,和sign比较是否相等,然后调用短信服务(传送手机号来发送验证码)

8:把验证码,设备id,CPK,以及验证码头码更新进以did为key的缓存中,返回用CPK对(生成的验证码头码)加密head_code

9:客户端把返回的验证码头码保存在本地变量中

手机验证码登录

10:构造签名:客户端使用CSK解密head_code,连同输入验证码,设备id,手机号,服务端时间戳,进行字符串拼接排序后使用sha1算法得到sign

11:数据加密:把手机号,验证码,head_code,时间戳,sign进行字符串拼接排序后使用SPK进行加密得到data,连同设备id一起发送给服务端

12:服务端用did查询到私匙SSK,客户端的公匙CPK,验证码,head_code,设备id;然后用SSK进行解密data得到sign,手机号,验证码,head_code,时间戳

13:比较签名:重复第10步sha1加密(验证码,head_code,设备id,手机号,服务端时间戳),得到sign-1,然后和sign比较

14:比较时间戳:然后用服务器时间和解密出来的时间戳比较,差值大于10分钟,返回错

15:比较设备id:检查设备id是否与上次点获取验证码的是否相同

16:比较验证码头码

17:调用短信服务验证code,不通过就返回错;通过后进行登录操作逻辑(全局映射目前C端,B端用户体系),最终生成用户的uid

18:把第12步中的用户自己的CPK,SSK一起保存,key为用户uid,并设置token(120分钟)与refresh token(7天) 的过期时间

19:服务端继续生成token和refresh token,然后用CPK对token及refresh token进行加密,得到sign-3,一起返回客户端

20:客户端把token和refresh token,uid,CSK保存在本地,使用的时候,用CSK解开,再用SPK加密,发送

登录状态中

10:客户端用本地私匙CSK对token解密,后用SPK对token进行再加密生成服务端可解析的token,及用户uid一起发送到服务端 {uid:xxx,token:SPK(CSK(xxxx))}

11:服务端通过用户uid找到对应的SSK,然后解密token,验证是否过期,如果过期,返回客户端让其再用本地私匙CSK对refresh token进行解密后, 再用SPK加密生成服务端可以解密的refresh token,调用/token/refresh接口发送到服务端{uid:xxx,refresh_token:SPK(CSK(xxxx))}, 再次用uid对应的SSK解密并验证refresh token,最后重新生成新的token,再经过CPK加密后返回,客户端更新本地的token。 反之refresh token也过期,提示客户端重新登录;如果在token没过期时调用了/token/refresh时,把当前的token取出经过CPK加密后返回

登出