使用nonce巩固接口签名安全_猿天地的技术博客_51CTO博客

blog.51cto.com · · 143 次点击 · · 开始浏览    

前面我们有讲过如何进行API的安全控制,其中包括数据加密,接口签名等内容。详细可以参考我下面两篇文章:
-《前后端API交互如何保证数据安全性》请添加链接描述
-《再谈前后端API签名安全?》请添加链接描述
在签名部分,通过时间戳的方式来判断当前请求是否有效,目的是为了防止接口被多次使用。但是这样并不能保证每次请求都是一次性的,今天给大家介绍下如何保证请求一次性?
首先我们来回顾一些时间戳判断的原理:客户端每次请求时,都需要进行签名操作,签名中会加上signTime参数(当前请求时间戳)。HTTP请求从发出到达服务器的正常时间不会很长,当服务器收到HTTP请求之后,首先进行签名检查,通过之后判断时间戳与当前时间相比较,是否超过了一定的时间,这个时间我们可以自行决定要多长,比如1分钟,2分钟都可以,时间长点可以防止客户端和服务器时间不一致的问题,如果超过了则认为是非法的请求。
假设我们的请求有效期是1分钟,如果黑客得到了我们的请求地址,在1分钟之内是可以重复请求多次的,因为这种方式不能保证请求仅一次有效。
基于nonce的方式可以解决重复使用的问题,最开始知道nonce是在广点通的接口中看到的,如下图所示:
使用nonce巩固接口签名安全
可以看到腾讯这边的接口也是基于时间戳和nonce来控制的。
nonce是随机字符串,每次请求时都要保证不同,你可以用uuid,可以用别的算法,也可以用随机加时间戳等等,只要不重复就行。
在后端我们验证的时候,将nonce参数存储起来,至于是存储在本地内存中,数据库中,redis,布隆过滤器中这就看你自己的需求了。
处理HTTP请求时,首先判断该请求的nonce参数是否在存在,如果存在则认为是非法请求。如果不存在则是合法请求,让后将该nonce存储起来,防止下次重复使用。
这种方式的弊端也很明显,那就是nonce的存储会越来越大,验证nonce是否存在的时间会越来越长。
如何解决存储问题?
可以用时间戳+nonce同时使用,相互配合,取长补短。
首先我们根据时间戳判断是否超过了一定的时间范围,如果超过了就直接拒绝,没有超过继续验证nonce是否使用过。
nonce没使用,存储起来,记录一个存储时间,通过定时任务去清除超过了时间戳验证的时间的nonce。这样的话我们只需要存储固定时间内的nonce数据,因为时间长的已经被时间戳的判断给拦截了,nonce的验证只需要验证时间有效期内的即可。
伪代码如下:

// 1.1获取签名时间,跟当前时间做对比,判断是否超出范围
Long signTime = 1XXXXL;
Long curTime = System.currentTimeMillis();
if (curTime - signTime > 60000) {
    // 超出了
    return;
}

// 1.2获取nonce判断是否存在,以redis举例
String nonce = "XXXXXX";
if (redisTemplate.hasKey(nonce)){
    //已经使用过了
} else {
    //没有使用,存储起来,设置过期时间为当前访问时间+判断请求过期的时间
    //这样就不用定时任务去清除之前的nonce,利用redis自动清除
   redisTemplate.opsForValue().set(nonce, "", 1, TimeUnit.MINUTES);
}

使用nonce巩固接口签名安全

尹吉欢
我不差钱啊
喜欢作者

本文来自:blog.51cto.com

感谢作者:blog.51cto.com

查看原文:使用nonce巩固接口签名安全_猿天地的技术博客_51CTO博客

143 次点击  
加入收藏 微博
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传