目录

应用在调用校验登录签名接口时,为了确保HTTPS传输的安全性,防止请求参数被篡改,应用需要在请求时携带请求参数的签名字符串,用于华为游戏服务器对请求参数进行校验。签名字符串的生成规则如下所示:

1、将请求参数中需要参与签名的参数,按参数名首字母的ASCII码将参数升序排序,若遇到相同首字母,则比较第二个字母,以此类推。
需要参与签名的参数是指接口说明中“是否参与签名”列为“是”且实际请求中携带了该参数,并且参数值不为空(null或"")。

2、将所有排序后的参数的参数值进行urlencode。

3、将所有参与签名的参数名和参数值(urlencode后)的键值对以“&”字符连接成待签名字符串,例如“a=xxxxxx&b=xxxxxxx&c=xxxxxxxxxxx...”。
生成待签名字符串的JAVA示例代码如下:

  1. private static String format(Map<String, String> params)
  2. {
  3.    StringBuffer base = new StringBuffer();
  4.    Map<String, String> tempMap = new TreeMap<String, String>(params);
  5.    //获取计算nsp_key的基础串      
  6.    try
  7.    {
  8.        for (Map.Entry<String, String> entry : tempMap.entrySet())
  9.        {
  10.            String k = entry.getKey();
  11.            String v = entry.getValue();
  12.            base.append(k).append("=").append(URLEncoder.encode(v, "UTF-8")).append("&");
  13.        }
  14.    }
  15.    catch (UnsupportedEncodingException e)
  16.    {
  17.        System.out.println("Encode parameters failed.");
  18.        e.printStackTrace();
  19.    }
  20.    String body = base.toString().substring(0, base.toString().length() - 1);
  21.    // 空格和星号转义    
  22.    body = body.replaceAll("\\+", "%20").replaceAll("\\*", "%2A");
  23.    return body;
  24. }

4、将待签名字符串使用游戏私钥按照RSA算法(SHA256WithRSA)进行签名,将签名后的字符串经过Base64编码,得到的字符串即为签名字符串。

说明:
如果游戏私钥必须保存在应用的服务端,则生成签名字符串必须在服务端执行。

JAVA示例代码如下:

  1. private static String generateCPSign(Map<String,String> requestParams,final String cpAuthKey)
  2. {
  3.    //对消息体中查询字符串按字典序排序并且进行URLCode编码      
  4.    String baseStr = format(requestParams);      
  5.    //用CP侧签名私钥对上述编码后的请求字符串进行签名    
  6.    String cpSign = sign(baseStr.getBytes(Charset.forName("UTF-8")), cpAuthKey);
  7.    return cpSign;
  8. }
  9. private static String sign(byte[] data, String privateKey)
  10. {
  11.    try
  12.    {
  13.        byte[] e = Base64.decodeBase64(privateKey);
  14.        PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(e);
  15.        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
  16.        PrivateKey privateK = keyFactory.generatePrivate(pkcs8KeySpec);
  17.        Signature signature = Signature.getInstance("SHA256WithRSA");
  18.        signature.initSign(privateK);
  19.        signature.update(data);
  20.        String signs = Base64.encodeBase64String(signature.sign());
  21.         return signs;
  22.    }
  23.    catch (Exception var)
  24.    {
  25.        System.out.println("SignUtil.sign error." + var);
  26.        return "";
  27.    }
  28. }