分享

如何保证APP与API通信安全,TOKEN冒用带来的风险很大?

 拼命奋斗的自己 2020-05-28

去看看淘宝开放平台的接口吧。简单来说,就是对请求参数进行签名,服务器和客户端约好秘钥,秘钥是不会在网络传输的过程中传递的,然后发起请求的时候对参数进行签名。别人即使拿到了token,想伪造一个请求,那还得知道秘钥才行。

TOKEN作为用户身份凭证并不能保证数据安全,别人通过抓包等方式很容易拿到TOKEN,带上TOKEN请求我们的API接口就能获取数据;其实换一个角度想:我们只需保证即使TOKEN被别人冒用,也不能调用我们API接口就行。

分享一个前后端使用AES和RSA混合加密通信的方案。

AES对称加密

首先看一下AES加密的示意图:

6f0e64843e1.jpeg

加密过程为:发送方(APP)使用密钥对参数明文进行AES加密获得密文,然后将密文和密钥一起发给接收方(服务端),接收方使用密钥对密文进行AES解密,得到参数明文。

AES由于是对称加密算法,特点就是加解密运算速度快;由于加解密使用的是同一个密钥,所以缺点就是在传输过程中会存在密钥泄露的风险。

RSA非对称加密

同样的,先来看一下RSA加密的示意图:

a714ba6a0f0.jpeg

首先接收方(服务端)生成一对RSA密钥(公钥、私钥),私钥自己保存同时公钥公布给发送方(APP)。

加密过程:发送方使用接收方公钥将参数明文进行RSA加密得到密文,并将密文发送给接收方,接收方使用自己的私钥对密文进行RSA解密得到参数明文。

同样的,服务端返回数据给APP时也可以使用私钥对数据进行签名,APP可以使用服务端的公钥来验证签名,从而判断数据是否来自合法的服务端。

RSA是非对称加密算法,加解密大量数据速度较慢,但由于加解密使用不同的密钥,所以安全度较高。

介于这两种加密方式各有优缺点,所以前后端加密通信方案通常采用AES对称加密算法对参数进行加密,RSA非对称加密算法则只用来对AES密钥进行加密,两种加密方式混合使用既不会太影响通信速度,又保证了通信安全。

为了防止重放攻击,我们还需要在AES+RSA混合加密的基础上再加入时间戳、随机字符串以及数字签名等校验逻辑。

为了防止中间人攻击,首先HTTPS是必须的,除此之外前后端还需要互相进行身份认证,确保通信没有被劫持。

前后端加密通信完整流程

准备工作:服务端生成RSA密钥对(公钥、私钥),公钥下发给APP,自己持有私钥;APP也需要生成RSA密钥对(公钥、私钥),公钥上传到服务端保存、私钥自己保留。

首先展示一下我用代码实现的前后端完整的加解密通信流程:

bc8439fbf60.jpeg

首先讲一下APP调用接口时的加密流程:

1.     随机生成一个AES加密算法的密钥,用于后续加密;

2.     使用服务端的RSA公钥对步骤1中生成的AES密钥明文进行RSA加密生成密钥密文;

3.     使用AES密钥明文对参数明文进行AES加密生成参数密文;

4.     生成当前时间的时间戳;

5.     生成一串随机字符串;

6.     将参数密文、AES密钥密文、时间戳、随机字符串进行MD5计算,得到md5值;

7.     使用APP自己的RSA私钥对md5值签名,得到签名值;

8.     最后将参数密文、AES密钥密文、时间戳、随机字符串、签名值一起发送到服务端;

再来讲一下服务端收到请求后的解密流程:

9.     对比请求参数中时间戳与服务器端获取的当前时间戳,判断两者差值是否在一定的时间之内,超过则认为请求过期;

10.  从系统缓存中查找参数中随机字符串是否已存在,如果已存在则认为是一次重复请求,不存在则将该随机字符串放入缓存;

11.  将参数密文、AES密钥密文、时间戳、随机字符串进行MD5计算,得到md5值

12.  使用客户端上传的RSA公钥验证参数中的签名是否来自合法授权的客户端,防止非法客户端篡改数据;

13.  使用自己的RSA私钥解密AES密钥密文,得到AES明文密钥;

14.  使用AES明文密钥解密参数密文得到参数明文;

15.  进行正常的业务处理流程;

16.  返回数据加密流程与客户端加密流程一致;

总结

要保证APP与API通信安全,首先要使用HTTPS协议,同时前后端还需要使用AES+RSA混合加密的方式来对数据进行加密,另外为了防止重放攻击、中间人攻击,还需要在数据加密的基础上加入时间戳、随机字符串以及数字签名等校验手段进一步提高通信的安全性

 

在app开放接口API的设计中,避免不了的就是安全性问题。

一、https协议

对于一些敏感的API接口,需要使用https协议。

https是在http超文本传输协议加入SSL层,它在网络间通信是加密的,所以需要加密证书。

二、签名设计

原理:用户登录后向服务器提供用户认证信息(如账户和密码),服务器认证完后给客户端返回一个Token令牌,用户再次获取信息时,带上此令牌,如果令牌正确,则返回数据。对于获取Token信息后,访问用户相关接口,客户端请求的url需要带上如下参数:

时间戳:timestamp

Token令牌:token

然后将所有用户请求的参数按照字母排序(包括timestamp,token),然后更具MD5加密(可以加点盐),全部大写,生成sign签名,这就是所说的url签名算法。然后登陆后每次调用用户信息时,带上sign,timestamp,token参数。

其最终的原理是减小明文的暴露次数;保证数据安全的访问。

具体实现如下:

1. 客户端向服务器端发送用户认证信息(用户名和密码),服务器端接收到请求后,验证用户信息是否正确。

如果正确:则返回一个唯一不重复的字符串(一般为UUID),然后在Redis(任意缓存服务器)中维护Token----Uid的用户信息关系,以便其他API对token的校验。

如果错误:则返回错误码。

2.服务器设计一个url请求拦截规则

(1)判断是否包含timestamp,token,sign参数,如果不含有返回错误码。

(2)判断服务器接到请求的时间和参数中的时间戳是否相差很长一段时间(时间自定义如半个小时),如果超过则说明该 url已经过期(如果url被盗,他改变了时间戳,但是会导致sign签名不相等)。

(3)判断token是否有效,根据请求过来的token,查询redis缓存中的uid,如果获取不到这说明该token已过期。

(4)根据用户请求的url参数,服务器端按照同样的规则生成sign签名,对比签名看是否相等,相等则放行。(自然url签名 也无法100%保证其安全,也可以通过公钥AES对数据和url加密,但这样无法确保公钥丢失,所以签名只是很大程度上保证安全)。

希望采纳!

 

c721865bacd.jpeg

我觉得有两个方面需要考虑

1.保证app不容易破解

2.保证通信过程中不被授信方拦截解密(用户自己拦截)

以上做法基本就可以解决通信安全问题。另外安全只是相对的没有绝对的安全

 

大部分回答的不是提问者问的吧?token冒用有可能导致你的服务端完全暴露给攻击者。相当于小偷夜间撬开了被盗者的家门,随后自己想想吧。

防范措施目前我能想到可能有以下几种:

https

token设置生效时间

token注销/强T

客户端和服务端动态同步更新

 

当下网络上,“token”技术的推广(力度),应该引起相关部门“警觉”了吧?“token”的固有问题那么危险,那么多的“推广人”真的不懂、不不知道吗?搞公共安全的公司,不应该站出来吗?

 

关于这一点

我是采用的双token来实现的

一个长时效token例如一个星期过期

一个短时效的token 大概一个小时或者两个小时或者更短

短时效token过期并且长时效token没有过期就重新下发短时效token

如果两个token都过期就需要用户重新登录

这样就解决了用户登录次数和token安全风险矛盾问题

 

 

按照我之前的经验通常是用通信密钥随机数时间戳进行随机加密,服务端通过通信密钥获得约定的私钥,然后根据传入的时间戳和随机数使用相同的加密方法获得认证值,然后比对客户端和服务端的认证,只是否一致,如果一致的话,则放行如果不一致的话就拦截。由于时间出和随机数是随机变更的,因此每次加密出来的token是不一样的,因此可以在一定程度上防止T O K E N冒用。

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多