zoukankan      html  css  js  c++  java
  • API接口签名验证2

    http://www.jianshu.com/p/d47da77b6419

    系统从外部获取数据时,通常采用API接口调用的方式来实现。请求方和�接口提供方之间的通信过程,有这几个问题需要考虑:

    1、请求参数是否被篡改;

    2、请求来源是否合法;

    3、请求是否具有唯一性。

    今天跟大家探讨一下主流的通信安全解决方案。

    参数签名方式

    这种方式是主流。它要求调用方按照约定好的算法生成签名字符串,作为请求的一部分,接口提供方验算签名即可知是否合法。步骤通常如下:

    ①接口提供方给出appid和appsecret

    ②调用方根据appid和appsecret以及请求参数,按照一定算法生成签名sign

    ③接口提供方验证签名

    生成签名的步骤如下:

    ①将所有业务请求参数按字母先后顺序排序

    ②参数名称和参数值链接成一个字符串A

    ③在字符串A的首尾加上appsecret组成一个新字符串B

    ④对字符串进行md5得到签名sign

    假设请求的参数为:f=1,b=23,k=33,排序后为b=23,f=1,k=33,参数名和参数值链接后为b23f1k33,首尾加上appsecret后md5:
    md5(secretkey1value1key2value2...secret)。

    签名的php版本实现:

        public static function sign($appSecret, $params) {
        if (!is_array($params)) 
            $params = array();
    
        ksort($params);
        $text = '';
        foreach ($params as $k => $v) {
            $text .= $k . $v;
        }
    
        return md5($appSecret . $text . $appSecret);
    }
    

    接口调用方的请求地址类似于:

    /api/?f=1&b=23&k=33&sign=signValue
    

    以上签名方法安全有效�地解决了参数被篡改和身份验证的问题,如果参数被篡改,没事,因为别人无法知道appsecret,也就无法重新生成新的sign。

    这里使用了md5的算法进行签名,也可以自行选择其他签名方式,例如RSA,SHA等。

    另外,多说一句,微信公众号开发时,验证服务器地址的有效性也采用了类似的方法,只是生成签名的方法不一样。

    请求唯一性保证

    md5签名方法可以保证来源及请求参数的合法性,但是请求链接一旦泄露,可以反复请求,对于某些拉取数据的接口来说并不是一件好事,相当于是泄露了数据。

    在请求中带上时间戳,并且把时间戳也作为签名的一部分,在接口提供方对时间戳进行验证,只允许一定时间范围内的请求,例如1分钟。因为请求方和接口提供方的服务器可能存在一定的时间误差,建议时间戳误差在5分钟内比较合适。允许的时间误差越大,链接的有效期就越长,请求唯一性的保证就越弱。所以需要在两者之间衡量。

    秘钥的保存

    在签名的过程中,起到决定性作用之一的是appsecret,因此如何保存成为关键。我们分类讨论。

    接口调用方的代码跑在服务器的情况比较好办,除非服务器被攻陷,否则外接无法知道appsecret,当然,要注意不能往日志里写入appsecret的值,其他敏感值也禁止写入日志,如账号密码等信息。

    假如是客户端请求接口,就需要多想一步了。假如把appsecret硬编码到客户端,会有反编译的风险,特别是android。可以在客户端登陆验证成功后,返回给客户端的信息中带上appsecret(当然,返回的数据也可能被拦截,真是防不胜防啊。。。)。特别说明一下,在android开发中,假如硬要把appsecret硬编码,建议把appsecret放到NDK中编译成so文件,app启动后去读取。

    TOTP:Time-based One-time Password Algorithm(基于时间的一次性密码算法)

    在一些小型项目中,可能不需要复杂的签名校验,只需要�做调用方的身份验证。TOTP(rfc6238)即可满足。

    TOTP是基于时间的一次性算法,客户端和服务器端约定秘钥,加入时间作为运算因子得到一个6位数字。客户端请求服务端时生成一个6位数字,服务端使用相同算法验证这个6位数字是否合法。

    下面再展开一下讨论,跟本文讨论的主题关系不大。

    TOTP允许�客户端和服务器端存在时间误差,如口令在N分钟内有效。给出一下源码供大家参考:

    与TOTP类似的还有 HTOP,它是基于次数的验证算法。这里不展开讨论。

    TOTP流程

    基于TOTP还有很多应用,例如动态的登录口令。用户登录时,除了需要输入设置的密码外,还需要输入动态密码,每个用户的秘钥都不一样,用户的手机端安装一个app即可实现,动态口令每N分钟变化一次。android客户端在各大应用市场搜索 google-authenticator,如 百度应用市场,ios客户端在appstore也可搜索得到。下面给出部分下载链接:

    支付宝、QQ令牌、银行客户端等这些手机客户端中也有类似的应用,在验证密码之后会多出一道动态口令的验证,他们使用的方案都类似于google-authenticator。

    大公司的运维人员,甚至是所有员工登录内部OA系统(单点登录),都需要PIN+令牌码的双重验证(PIN是自行设置的固定密码,令牌码则是动态口令码),他们通常使用RSA SecurID双因素动态口令身份认证解决方案。

     


    作者:hellojammyPlus
    链接:http://www.jianshu.com/p/d47da77b6419
    來源:简书
    著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
  • 相关阅读:
    Junit单元测试
    win7的6个网络命令
    WOJ1024 (POJ1985+POJ2631) Exploration 树/BFS
    WOJ1022 Competition of Programming 贪心 WOJ1023 Division dp
    woj1019 Curriculum Schedule 输入输出 woj1020 Adjacent Difference 排序
    woj1018(HDU4384)KING KONG 循环群
    woj1016 cherry blossom woj1017 Billiard ball 几何
    woj1013 Barcelet 字符串 woj1014 Doraemon's Flashlight 几何
    woj1012 Thingk and Count DP好题
    woj1010 alternate sum 数学 woj1011 Finding Teamates 数学
  • 原文地址:https://www.cnblogs.com/lxwphp/p/15454762.html
Copyright © 2011-2022 走看看