/* Title: SHA1签名 */

系统参数说明

名称 类型 必选 描述
appId string Y 入驻服务开发者(SP)的应用唯一标识码,由开放平台统一分配并提供(一个SP可自行创建多个应用号)
timestamp int Y 当前Unix时间戳,请保证请求服务器时间正确,有些API接口是有时效性要求的
ver string Y 协议版本号,统一取值为1.0
sign string Y 验证码,生成规则详见下面的说明,其中app_key是由开放平台统一分配并提供的SP私钥

签名描述

签名机制 SHA1 加密

  1. 对所有传入参数(含系统参数和接口参数)按照字段名的 ASCII 码从小到大排序(字典序)后,使用 URL 键值 对的格式。 (即 key1=value1&key2=value2…)拼接成字符串 string1, 注意:值为空的参数不参与签名,所有请求参数值都需要进行URL编码。
  2. 在 string1 最 后 拼 接 上 key=app_key得 到 stringSignTemp 字 符 串 , 并 对 stringSignTemp 进行 sha1 运算,再将得到的字符串所有字符转换为大写, 得到 sign 值 signValue。
  3. 对传入参数中所有键值对的 value 进行 urlencode 转码后重新拼接成字符串 string2。
  4. 将 sign=signValue拼接到string2后面得到最终的 参数 字符串。

Java代码示例


    //生成get 方式 带签名的请求URL 
    public static void main(String[] args) {
        String app_key = "xxxxxxxxxxx";     //开发者帐号对应的key. 请开发者谨慎保管此值。
        Map<String, String> map = new HashMap<String,String>();

        map.put("appId","xxxxxxxxxx");  //开发者帐号对应的10位ID ,所有接口参数都必须有此参数。
        map.put("param1_keyname", "Parm1_vaule");   //接口需要的参数1 
        map.put("param2_keyname", "Parm2_vaule");   //接口需要的参数2 。。。 等等

        String getUrl = buildURL("http://api.cnlive.com/open/api2/xxxxxxx",map, app_key);
        System.out.println(getUrl);  
    }

    //生成post方式的请求参数签名
    public static void main(String[] args) {
        String app_key = "xxxxxxxxxxx";     //开发者帐号对应的key. 请开发者谨慎保管此值。
        Map<String, String> map = new HashMap<String,String>();

        map.put("appId","xxxxxxxxxx");  //开发者帐号对应的10位ID ,所有接口参数都必须有此参数。
        map.put("param1_keyname", "Parm1_vaule");   //接口需要的参数1 
        map.put("param2_keyname", "Parm2_vaule");   //接口需要的参数2 。。。 等等

        String post_param_signed = sign(map, app_key);
        System.out.println(post_param_signed);  
    }   

  /**
 * 生成URL
 * @param url
 * @param params
 * @param app_key
 * @return
 */
    public static String buildURL(String url,Map<String,String> params,String app_key){
        Map<String,String> map = order(params);
        if(map.containsKey("sign")){
            map.remove("sign");
        }
        String str = mapJoin(map,true,false);
        String sign = SHA1.SHA1Digest(str+"&key="+app_key).toUpperCase();
        map.put("sign", sign);
        return url+"?"+mapJoin(map, false, true);
    }

    /**
 * Map key 排序
 * @param map
 * @return
 */
    private static Map<String,String> order(Map<String, String> map){
        HashMap<String, String> tempMap = new LinkedHashMap<String, String>();
        List<Entry<String, String>> infoIds = new ArrayList<Entry<String, String>>( map.entrySet());

        Collections.sort(infoIds, new Comparator<Entry<String, String>>() {
            public int compare(Entry<String, String> o1,Entry<String, String> o2) {
                return (o1.getKey()).toString().compareTo(o2.getKey());
            }
        });

        for (int i = 0; i < infoIds.size(); i++) {
            Entry<String, String> item = infoIds.get(i);
            tempMap.put(item.getKey(), item.getValue());
        }
        return tempMap;
    }

    /**
 * url 参数串连
 * @param map
 * @param keyLower
 * @param valueUrlencode
 * @return
 */
    private static String mapJoin(Map<String, String> map,boolean keyLower,boolean valueUrlencode){
        StringBuilder stringBuilder = new StringBuilder();
        for(String key :map.keySet()){
            if(map.get(key)!=null&&!"".equals(map.get(key))){
                try {
                    stringBuilder.append(key)
                                 .append("=")
                                 .append(valueUrlencode?URLEncoder.encode(map.get(key),"utf-8").replace("+", "%20"):map.get(key))
                                 .append("&");
                } catch (UnsupportedEncodingException e) {
                    e.printStackTrace();
                }
            }
        }
        if(stringBuilder.length()>0){
            stringBuilder.deleteCharAt(stringBuilder.length()-1);
        }
        return stringBuilder.toString();
    }