基于腾讯开放平台签名参数sig说明以及retrofit请求进行参数加密

腾讯开放平台第三方应用签名参数sig说明文档

Step 1. 构造源串

源串是由3部分内容用“&”拼接起来的:

HTTP请求方式 & urlencode(uri) & urlencode(a=x&b=y&...)

源串构造步骤如下:

第1步:将请求的URI路径进行URL编码(URI不含host,URI示例:/v3/user/get_info)。
请开发者关注:URL编码注意事项,否则容易导致后面签名不能通过验证。

第2步:将除“sig”外的所有参数按key进行字典升序排列。

注:除非OpenAPI文档中特别标注了某参数不参与签名,否则除sig外的所有参数都要参与签名。

第3步:将第2步中排序后的参数(key=value)用&拼接起来,并进行URL编码。
请开发者关注:URL编码注意事项,否则容易导致后面签名不能通过验证。

第4步:将HTTP请求方式(GET或者POST)以及第1步和第3步中的字符串用&拼接起来。
注:Java_SDK_V3.0.6仅支持POST方式,如果用GET可能导致一直计算sig不正确。

Step 2. 构造密钥
得到密钥的方式:在应用的appkey末尾加上一个字节的“&”,即appkey&,例如:228bf094169a40a3bd188ba37ebe8723&

Step 3. 生成签名值

  1. 使用HMAC-SHA1加密算法,使用Step2中得到的密钥对Step1中得到的源串加密。
    (注:一般程序语言中会内置HMAC-SHA1加密算法的函数,例如PHP5.1.2之后的版本可直接调用hash_hmac函数。)

  2. 然后将加密后的字符串经过Base64编码。
    (注:一般程序语言中会内置Base64编码函数,例如PHP中可直接调用 base64_encode() 函数。)

  3. 得到的签名值结果如下:
    FdJkiDYwMj5Aj1UG2RUPc83iokk=

public class BasicParamsInterceptor implements Interceptor {
    public static String TAG="BasicParamsInterceptor";

    private BasicParamsInterceptor() {

    }

    @Override
    public Response intercept(Chain chain) throws IOException {

        Request request = chain.request();
        Request.Builder requestBuilder = request.newBuilder();
        //===========给参数进行加密 start===================
        String signParam="";
        if("POST".equals(request.method())){
            String url="你的请求url";
            String encodeURL="";//URL编码后的请求url
            String encodeSortParams="";//URL编码后的升序参数体
            HashMap paramsMap =new  HashMap();
            //step1.1  将请求的URI路径进行URL编码
            encodeURL=URLEncoder.encode(url,"utf-8");
            Log.d(TAG,"url="+url);
            Log.d(TAG,"encode_url="+ encodeURL);
            StringBuilder sb = new StringBuilder();
            if (request.body() instanceof FormBody) {
                FormBody body = (FormBody) request.body();
                int bodySize=body.size();
             
                for (int i = 0; i < bodySize; i++) {
                    paramsMap.put(body.encodedName(i),body.encodedValue(i));
                    sb.append(body.encodedName(i) + "=" + body.encodedValue(i) + ",");
                }
                sb.delete(sb.length() - 1, sb.length());
                Log.d(TAG, "║ RequestParams:{"+sb.toString()+"}");
                Collection keyset= paramsMap.keySet();
                List list = new ArrayList(keyset);
                //step1.2   对key键值按字典升序排序
                Collections.sort(list);
                StringBuilder sortParams = new StringBuilder();
                int sortParamSize=list.size();
                //step1.3   将第2步中排序后的参数(key=value)用&拼接起来,并进行URL编码。
                for (int i = 0; i < sortParamSize; i++) {
                    sortParams.append(list.get(i)+"="+paramsMap.get(list.get(i)));
                    if(i!=sortParamSize-1){
                        sortParams.append("&");
                    }
                }
                Log.d(TAG,"数据字典升序后:key键值="+sortParams.toString());
                encodeSortParams=URLEncoder.encode(sortParams.toString(),"utf-8");//进行URL编码的 key键值
                Log.d(TAG,"数据字典升序并encode="+encodeSortParams);

                //step1.4   将HTTP请求方式(GET或者POST)以及第1步和第3步中的字符串用&拼接起来。
                StringBuilder bufferStep1=new StringBuilder();
                bufferStep1.append(request.method());
                bufferStep1.append("&");
                bufferStep1.append(encodeURL);
                bufferStep1.append("&");
                bufferStep1.append(encodeSortParams);
                Log.d(TAG,"拼接后的step1="+bufferStep1.toString());
                try {
                    //step 2
                    String key="你的key"+"&"
                    
                    //step3      
                    signParam=Util.HMACSha1(bufferStep1.toString(),key);
                    Log.d(TAG,"signParam="+signParam);
                } catch (NoSuchAlgorithmException e) {
                    e.printStackTrace();
                } catch (InvalidKeyException e) {
                    e.printStackTrace();
                }
            }
        }
        paramsMap.put("sign",signParam.trim());
        //===========给参数进行加密 end===================
}
/**
     * 获取 hmacSha1 并返回Base64编码后的字符串
     *
     * @param base
     * @param key
     * @return
     * @throws NoSuchAlgorithmException
     * @throws InvalidKeyException
     */
    public static String HMACSha1(String base, String key) throws NoSuchAlgorithmException, InvalidKeyException {
        if (TextUtils.isEmpty(base) || TextUtils.isEmpty(key)) {
            return "";
        }
        String type = "HmacSHA1";
        SecretKeySpec secret = new SecretKeySpec(key.getBytes(), type);
        Mac mac = Mac.getInstance(type);
        mac.init(secret);
        byte[] digest = mac.doFinal(base.getBytes());

        return Base64.encodeToString(digest, Base64.DEFAULT);

    }

你可能感兴趣的:(基于腾讯开放平台签名参数sig说明以及retrofit请求进行参数加密)