zoukankan      html  css  js  c++  java
  • (办公)接口签名的思考

    1.什么是接口签名?

    :接口开发是各系统之间对接的重要方式,其数据是通过开放的互联网传输,对数据的安全性要有一定要求。为了提高传输过程参数的防篡改性,签名sign的方式是目前比较常用的方式。

     重点:请求身份是否合法?请求参数是否被恶意篡改,请求是否唯一.

    2.怎么提供一个安全性高的接口?

    :

    2.1. 请求身份:

        Appkey(公钥)开发者标识确定唯一,AppSecret密钥(用于接口加密,确保生成参数不被猜测)有个缺点密钥让人家知道还是完蛋了.

    2.2. 接口加参数

    接口加个参数timestamp时间戳,格式为yyyy-mm-dd HH:mm:ss,例如:2013-05-06 13:52:03(建议传入当前时间),防止同一时间内点击两次.

       接口加个参数Appkey(公钥).

      接口加个参数sign签名字段:签名sign具体算法为:根据传入参数名称(签名sign除外)将所有请求参数按照首字母先后顺序排序,md5(密钥+除密钥外排好序的参数串+密钥)后转换为大写字母,注意编码,统一为utf8。注意要有AppSecret密钥.

    类似下面这个样子:

          http://xxxx?

    method=xx

    &appkey=xx

    ×tamp=2014-12-26 10:27:26

    &format=json

    &sign=生成的签名

    以上两步,解决了防止防止篡改,参数正确,但是没有解决着重复请求参数伪造二次请求的隐患。也就是重放攻击。

    2.3.timestamp+nonce方案

    nonce指唯一的随机字符串,用来标识每个被签名的请求。通过为每个请求提供一个唯一的标识符,服务器能够防止请求被多次使用(记录所有用过的nonce以阻止它们被二次使用)。

    然而,对服务器来说永久存储所有接收到的nonce的代价是非常大的。可以使用timestamp来优化nonce的存储。

    假设允许客户端和服务端最多能存在6分钟的时间差,同时追踪记录在服务端的nonce集合。当有新的请求进入时,首先检查携带的timestamp是否在6分钟内,如超出时间范围,则拒绝,然后查询携带的nonce,如存在已有集合,则拒绝。否则,记录该nonce,并删除集合内时间戳大于6分钟的nonce(可以使用redisexpire,新增nonce的同时设置它的超时失效时间为6分钟)。

       另外除了公钥密钥,还可以用token身份验证。

       服务端验证账号密码,生成token,存储30分钟,token发给前端,前端每次请求带上这个token。但是仍然存在着安全隐患,token被劫持,伪造请求和篡改参数。

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

    系统可以设定一些规则:

    1. 公钥密钥有自己的系统生成.
    2. 接口有效性6分钟.
    3. 接口调用频率:1毫秒以上.
    4. 数据参数安全,验证签名.
    5. 具体算法为:根据传入参数名称(签名sign除外)将所有请求参数按照首字母先后顺序排序,md5(密钥+除密钥外排好序的参数串+密钥)后转换为大写字母。

       还有就是排序参数,如果是只调用web接口不超过3,建议不要写字母排序方法,浪费时间.

    下面提供md5utils:

    使用: MD5Utils.MD5Encode(str,"utf8");


    import java.security.MessageDigest;

    public class MD5Utils {
        private static final String hexDigIts[] = {"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "a", "b", "c", "d", "e", "f"};

        /**
         * MD5加密
         *
         * @param origin      字符
         * @param charsetname 编码
         * @return
         */
        public static String MD5Encode(String origin, String charsetname) {
            String resultString = null;
            try {
                resultString = new String(origin);
                MessageDigest md = MessageDigest.getInstance("MD5");
                if (null == charsetname || "".equals(charsetname)) {
                    resultString = byteArrayToHexString(md.digest(resultString.getBytes()));
                } else {
                    resultString = byteArrayToHexString(md.digest(resultString.getBytes(charsetname)));
                }
            } catch (Exception e) {
            }
            return resultString;
        }

        public static String byteArrayToHexString(byte b[]) {
            StringBuffer resultSb = new StringBuffer();
            for (int i = 0; i < b.length; i++) {
                resultSb.append(byteToHexString(b[i]));
            }
            return resultSb.toString();
        }

        public static String byteToHexString(byte b) {
            int n = b;
            if (n < 0) {
                n += 256;
            }
            int d1 = n / 16;
            int d2 = n % 16;
            return hexDigIts[d1] + hexDigIts[d2];
        }

    }

    另外相同的参数,相同的接口重复的调用,可以直接返回:

    {

        "code": -1,

        "msg": "调用频率太过频繁"

    }

     虽然有些攻击还是防不到,但是能让你装装逼,让客户看到哇,我这次选的系统接口,很专业。(确实,让我访问接口每访问一次都要加签名什么的,搞得我很难受。)

      内容借鉴:(简书作者:Joker_Coding,链接:https://www.jianshu.com/p/ad410836587a)

     

      

      

  • 相关阅读:
    CodeForces 288A Polo the Penguin and Strings (水题)
    CodeForces 289B Polo the Penguin and Matrix (数学,中位数)
    CodeForces 289A Polo the Penguin and Segments (水题)
    CodeForces 540C Ice Cave (BFS)
    网站后台模板
    雅图CAD
    mbps
    WCF学习-协议绑定
    数据库建表经验总结
    资源位置
  • 原文地址:https://www.cnblogs.com/historylyt/p/11119061.html
Copyright © 2011-2022 走看看