首页 > 编程知识 正文

访问接口服务器被拒绝(借口拒绝连接)

时间:2023-05-04 01:06:19 阅读:95436 作者:1847

接口的安全问题

身份合法吗? 请求参数是否被篡改? 请求是唯一的吗?

AccessKeySecretKey (开放平台)

请求身份

给开发者分配访问密钥(开发者id,确保唯一性)和secret密钥),用于接口加密,难以覆盖,生成算法难以推测。

防止篡改

参数签名

将包含AccessKey的请求参数按照请求参数名称的字母顺序升序排列,然后使用URL键和值对的形式,即key1=value1key2=value2…连接到字符串stringA。 在stringA的最后连接Secretkey,得到字符串stringSignTemp; 对stringSignTemp进行MD5运算,将得到的字符串中的所有字符转换为大写,得到sign值。 要求携带参数AccessKey和Sign,必须持有合法身份AccessKey和正确的签名Sign才能释放。 这样就解决了认证和参数篡改的问题,即使请求参数被劫持,也无法获取SecretKey (仅用于本地加密,不参与网络传输),因此无法伪造合法请求。

重放攻击

解决了请求参数被篡改的危险性,但也有重复使用请求参数伪造二次请求的危险性。

时间无方案

nonce是用于标识每个已签名请求的唯一随机字符串。 通过为每个请求指定唯一的标识符,服务器可以防止请求被多次使用。 记录所有使用过的nonce,使其不被使用两次。

但是,对服务来说,永久保存接收到的所有nonce的成本非常高。 可以使用timestamp优化nonce的存储。

假设客户端和服务器端之间最多有15分钟的时间差,跟踪服务器端记录的nonce集合。 如果有新的请求,首先检查携带的timestamp是否在15分钟以内,如果在时间范围外则拒绝,向携带的nonce询问,如果有现有的收藏则拒绝。 否则,记录该nonce,删除集合中时间戳为15分钟以上的nonce。 可以使用redis expire在添加nonce的同时将超时设置为15分钟。

实现

请求接口: http://api.test.com/test? name=hellohome=世界=Java

客户端

生成与当前时间戳timestamp=now唯一的随机字符串nonce=random,并且请求参数名称中的非空请求参数(包括AccessKey ),按字母升序排列stringa='访问密钥=访问主机=世界名称=hello work=乔拼接密钥安全密钥='访问主机=访问主机=将ndomsecretkey=secretkey MD5定义为大写的sign=MD5 (字符串签名. toUpperCase ); 最终要求http://api.test.com/test吗? name=hellohome=世界=Javatamp=nowno

nce=nonce&sign=sign;

服务端

Token&AppKey(APP)

在APP开放API接口的设计中,由于大多数接口涉及到用户的个人信息以及产品的敏感数据,所以要对这些接口进行身份验证,为了安全起见让用户暴露的明文密码次数越少越好,然而客户端与服务器的交互在请求之间是无状态的,也就是说,当涉及到用户状态时,每次请求都要带上身份验证信息。

Token身份验证

用户登录向服务器提供认证信息(如账号和密码),服务器验证成功后返回Token给客户端;客户端将Token保存在本地,后续发起请求时,携带此Token;服务器检查Token的有效性,有效则放行,无效(Token错误或过期)则拒绝。安全隐患:Token被劫持,伪造请求和篡改参数。

Token+AppKey签名验证

与上面开发平台的验证方式类似,为客户端分配AppKey(密钥,用于接口加密,不参与传输),将AppKey和所有请求参数组合成源串,根据签名算法生成签名值,发送请求时将签名值一起发送给服务器验证。

这样,即使Token被劫持,对方不知道AppKey和签名算法,就无法伪造请求和篡改参数。再结合上述的重发攻击解决方案,即使请求参数被劫持也无法伪造二次重复请求。

实现

登陆和退出请求

登陆和退出流程

后续请求

客户端

和上述开放平台的客户端行为类似,把AccessKey改为token即可。

服务端

服务端流程

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。