# 研学开放平台JS-SDK签名算法

# 签名字段说明

签名字段 描述
appid 开放平台-系统设置-应用管理 (opens new window)申请的appid(注:可使用知网研学账号登录)
noncestr 随机字符串
js_ticket 调用开放平台接口获取的临时票据,获取方式详见:知网研学开放平台文档-研学开放平台JSSDK-TICKET获取 (opens new window)
timestamp 时间戳
url url必须是调用JS接口页面的域名,同时和申请appid时填写的主站域名一致

# 签名规则

签名生成规则如下: 对所有待签名参数按照字段名的ASCII 码从小到大排序(字典序)后,使用URL键值对的格式(即key1=value1&key2=value2…)拼接成字符串string1。这里需要注意的是所有参数名均为小写字符。最后对string1sha1加密,如下示例:


Map<String, String> params = new HashMap<>();
params.put("appid", appid);
params.put("js_ticket", ticket);
params.put("noncestr", noncestr);
params.put("timestamp", timestamp);
params.put("url", url);
String signatureNew = getSignature(params);
        
//签名    
private String getSignature(Map<String, String> params) {
    // 按照字段名的ASCII码从小到大排序
    String[] keys = params.keySet().toArray(new String[0]);
    Arrays.sort(keys);
    // 拼接成字符串
    StringBuilder stringToSign = new StringBuilder();
    for (String key : keys) {
        stringToSign.append(key).append("=")
        .append(params.get(key))
        .append("&");
    }
    // 去掉最后一个多余的"&"
    String string1 = stringToSign
    					.substring(0, stringToSign.length() - 1);
    try {
        MessageDigest md = MessageDigest.getInstance("SHA-1");
        byte[] messageDigest = md.digest(string1.getBytes());
        BigInteger no = new BigInteger(1, messageDigest);
        String hashtext = no.toString(16);
        while (hashtext.length() < 40) {
        hashtext = "0" + hashtext;
    }
    return hashtext;

    } catch (NoSuchAlgorithmException e) {
    	log.error("签名失败失败:", e);
    	return null;
    }
}

# 注意事项

  • 签名用的noncestrtimestamp必须与openSDK.config中的nonceStrtimestamp相同。

  • 签名用的url必须是调用JS接口页面的域名,同时和申请appid时填写的主站域名一致。

  • 出于安全考虑,开发者必须在服务器端实现签名的逻辑。