API接口安全性设计

作者: 一一道长一一 | 来源:发表于2016-05-20 16:59 被阅读16004次

    接口的安全性主要围绕Token、Timestamp和Sign三个机制展开设计,保证接口的数据不会被篡改和重复调用,下面具体来看:

    Token授权机制:用户使用用户名密码登录后服务器给客户端返回一个Token(通常是UUID),并将Token-UserId以键值对的形式存放在缓存服务器中。服务端接收到请求后进行Token验证,如果Token不存在,说明请求无效。Token是客户端访问服务端的凭证

    时间戳超时机制:用户每次请求都带上当前时间的时间戳timestamp,服务端接收到timestamp后跟当前时间进行比对,如果时间差大于一定时间(比如5分钟),则认为该请求失效。时间戳超时机制是防御DOS攻击的有效手段。

    签名机制:将 Token 和 时间戳 加上其他请求参数再用MD5或SHA-1算法(可根据情况加点盐)加密,加密后的数据就是本次请求的签名sign,服务端接收到请求后以同样的算法得到签名,并跟当前的签名进行比对,如果不一样,说明参数被更改过,直接返回错误标识。签名机制保证了数据不会被篡改。

    拒绝重复调用(非必须):客户端第一次访问时,将签名sign存放到缓存服务器中,超时时间设定为跟时间戳的超时时间一致,二者时间一致可以保证无论在timestamp限定时间内还是外 URL都只能访问一次。如果有人使用同一个URL再次访问,如果发现缓存服务器中已经存在了本次签名,则拒绝服务。如果在缓存中的签名失效的情况下,有人使用同一个URL再次访问,则会被时间戳超时机制拦截。这就是为什么要求时间戳的超时时间要设定为跟时间戳的超时时间一致。拒绝重复调用机制确保URL被别人截获了也无法使用(如抓取数据)。

    整个流程如下:

    1、客户端通过用户名密码登录服务器并获取Token

    2、客户端生成时间戳timestamp,并将timestamp作为其中一个参数

    3、客户端将所有的参数,包括Token和timestamp按照自己的算法进行排序加密得到签名sign

    4、将token、timestamp和sign作为请求时必须携带的参数加在每个请求的URL后边(http://url/request?token=123&timestamp=123&sign=123123123)

    5、服务端写一个过滤器对token、timestamp和sign进行验证,只有在token有效、timestamp未超时、缓存服务器中不存在sign三种情况同时满足,本次请求才有效

    在以上三中机制的保护下,

    如果有人劫持了请求,并对请求中的参数进行了修改,签名就无法通过;

    如果有人使用已经劫持的URL进行DOS攻击,服务器则会因为缓存服务器中已经存在签名或时间戳超时而拒绝服务,所以DOS攻击也是不可能的;

    如果签名算法和用户名密码都暴露了,那齐天大圣来了估计也不好使吧。。。。

    最后说一句,所有的安全措施都用上的话有时候难免太过复杂,在实际项目中需要根据自身情况作出裁剪,比如可以只使用签名机制就可以保证信息不会被篡改,或者定向提供服务的时候只用Token机制就可以了。如何裁剪,全看项目实际情况和对接口安全性的要求~

    我就是齐天大圣

    相关文章

      网友评论

      • SHAN某人:不错的接口安全设计思路
      • a064d1f028b8:timestamp是秒级的请求服务器时间也肯定对应不上啊,那签名不就变了么
      • 74764b78b7d8:时间戳的话国外用户差了时区不是就访问不了了?
        一一道长一一:@俺易大力 可以统一使用0时区来进行对齐
      • 丢了发型的男人:为什么调用接口就一定要有用户和密码?好多情况下是没有用户的,也就是说不需要登陆也能访问!比如app,那样接口又如何设置安全
        一一道长一一:客户端都有deviceId,可以当用户唯一ID来用,服务端可以根据deviceId来分配token,也可以直接拿deviceId当token用
      • zhangrui_jerry:感谢感谢,学习了!
      • 东流水_23f8:用session不就可以了,整那么麻烦.对于web程序来说,可以将token存储在cookie中,并进行类似的三个参数校验
        一一道长一一:也是一种思路,参数放在哪儿不重要,只要达到目的就行
      • Bo动:客户端的时间戳难道不可以通过修改系统时间来变化?
        一一道长一一:@云波丽 所以还需要一个跟系统对时的功能,这个可根据实际情况来定,一般用户改系统时间的情况还是不多的
      • Freedom_Coco:时间戳超时机制是防御DOS攻击的有效手段,这话没有理解到什么意思。如果抓到符合规则的url,在一个时间段内,连续请求上百次,上千次,时间戳是请求时获取的手机的时间,也一直在变,怎么防止DOS攻击呢?
      • Best_Kai:如果手机端改了本地时间,那么就会和当前时间有一定的差值,这个是怎么解决的?
        一一道长一一:@Best_Kai 拿到符合规则的url后,时间戳有效时间内会被缓存命中从而禁止访问,在有效时间外更不用说了,如果本地修改了时间戳,签名是过不去的。第二个问题,如果本地修改了时间,可以提供一个服务器对时的机制,在请求之前先获取服务器时间,当然这只是对小部分用户
      • 50a8a5cfa160:token附在请求参数里,这样token不就暴露了?别人拿着token按照签名算法就可以伪造了请求了。

        1人赞 回复
        一一道长一一: token具有时效性 可以是一次性的 也可以是在一段时间内有效 看你怎么做了

        别人拿走token可以在合法时间内操作,哈
        124f4014a474:@一一道长一一 对问这种问题的人表示呵呵。
        一一道长一一:@缘来甲壳虫 关键是他怎么能知道你的算法呢,况且一般算法里都要加盐的(就是只有你们内部知道的一个key)
        50a8a5cfa160:被人截获token ,使用同样的签名算法,例如md5,做sign,并且也在合法超市时间内
      • FX_SKY:token附在请求参数里,这样token不就暴露了?别人拿着token按照签名算法就可以伪造了请求了。
        幽灵柯南:@一一道长一一 加密算法不公开,就不是加密算法了
        一一道长一一:@FX_SKY 那么,他怎么知道你的算法呢?而且你的算法里肯定还是要加盐的
        一一道长一一:token具有时效性 可以是一次性的 也可以是在一段时间内有效 看你怎么做了
      • liunewshine:怎样保证签名算法不泄露?android还有jni可以防止,web前端呢。
        一一道长一一:@作为一只熊我很苗条 是的,web前端用https就行,要签名也行,记得使用js混淆,让别人破了就不好了
        YvMgLe:web前端签名没用,用https就好吧
      • echo_4c80:请教大神,时间戳怎么对齐呢?如果用户修改了手机的时间呢?或者不同服务器的存在时间差怎么处理?
        一一道长一一:@echo_4c80 可以弄一个获取服务器时间的接口,如果时间不对就从服务器上取,这种情况毕竟只是少数,不会调用太频繁的
      • 奋斗琵箁:web页面直接调用api,如何保证签名算法正确
        一一道长一一:@蜕变之路 基本不能了
        此博废弃_更新在个人博客:我也想知道,web的js混淆后能还原出签名算法吗?
      • riceeeeeeee:请问服务器端如何校验签名?客户端发的数据服务器不一定知道吧?
        一一道长一一:@HxH_RORO 两边签名算法一致就行
      • 3a400d27093f:请问时间戳是在什么时候生成的,登录成功就生成吗?如果我登录成功,但是在访问其他接口(需要Token信息的接口),不是立即访问,可能需要10分 20分钟后访问,这个时间要怎么规定呀?
        一一道长一一:@21梦love 时间戳是在发起请求时生成的 就是客户端请求的时间
      • baiyi:签名算法在客户端的话,反编译了之后一样能伪造啊
        幽灵柯南:@一一道长一一 前端js怎么加固都没用
        124f4014a474:android的话可以放到so文件里,再对so文件验证。
        一一道长一一:@8912cda5d927 客户端一般都会进行加固 反编译不了的 :blush:
      • 9fd91bce73f5:我现在就是属于齐天大圣都救不了的那种了 :joy:
      • Lucky_福星:不错,学习了,谢谢

      本文标题:API接口安全性设计

      本文链接:https://www.haomeiwen.com/subject/ivenrttx.html