基于騰訊開放平臺簽名參數sig說明以及retrofit請求進行參數加密

騰訊開放平臺第三方應用簽名參數sig說明文檔

Step 1. 構造源串

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

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

源串構造步驟如下:

第1步:將請求的URI路徑進行URL編碼(URI不含host,URI示例:/v3/user/get_info)。
<font color="red">請開發者關注:URL編碼注意事項,否則容易導致后面簽名不能通過驗證。</font>

第2步:<font color="red">將除“sig”外的所有參數</font>按key進行字典升序排列。

注:除非OpenAPI文檔中特別標注了某參數不參與簽名,否則除sig外的所有參數都要參與簽名。

第3步:將第2步中排序后的參數(key=value)用&拼接起來,并進行URL編碼。
<font color="red">請開發者關注:URL編碼注意事項,否則容易導致后面簽名不能通過驗證。</font>

第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<String, String> paramsMap =new  HashMap<String, String>();
            //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<String> keyset= paramsMap.keySet();
                List<String> list = new ArrayList<String>(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);

    }

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容