下载平台证书的时候,返回的状态码是401,错误信息如下图所示:
可以看到错误信息提示是错误的签名,于是就检查关于签名部分的代码,下面是从官网copy的生成签名的代码。
/**
* @Decription 计算签名值
* Authorization: <schema> <token>
* GET - getToken("GET", httpurl, "")
* POST - getToken("POST", httpurl, json)
* @Param null
* @Return java.lang.String
* @Author lmh
* @Date 2022/1/5 17:13
*/
String getToken(String method, HttpUrl url, String body){
String nonceStr = null;
long timestamp = 0;
String signature = null;
try {
nonceStr = "593BEC0C930BF1AFEB90B4A08C8FB242";
timestamp = System.currentTimeMillis() / 1000;
String message = buildMessage(method, url, timestamp, nonceStr, body);
System.out.println(message);
signature = sign(message.getBytes("utf-8"));
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return "mchid=\"" + 商户号 + "\","
+ "nonce_str=\"" + nonceStr + "\","
+ "timestamp=\"" + timestamp + "\","
+ "serial_no=\"" + 商户证书序列号 + "\","
+ "signature=\"" + signature + "\"";
}
/**
* @Decription 使用商户私钥对签名串进行SHA256 with RSA签名,base64编码之后
* @Param null
* @Return java.lang.String
* @Author lmh
* @Date 2022/1/6 18:07
*/
String sign(byte[] message) {
Signature sign = null;
String s = null;
try {
PrivateKey privateKey = this.getPrivateKey();
sign = Signature.getInstance("SHA256withRSA");
sign.initSign(privateKey);
sign.update(message);
s = Base64.getEncoder().encodeToString(sign.sign());
} catch (Exception e) {
e.printStackTrace();
}
return s;
}
/**
* @Decription 生成签名串
* @Param null
* @Return java.lang.String
* @Author lmh
* @Date 2022/1/6 18:06
*/
String buildMessage(String method, HttpUrl url, long timestamp, String nonceStr, String body) {
String canonicalUrl = url.encodedPath();
if (url.encodedQuery() != null) {
canonicalUrl += "?" + url.encodedQuery();
}
return method +"\\n"+"\n"
+ canonicalUrl+"\\n"+ "\n"
+ timestamp +"\\n"+ "\n"
+ nonceStr +"\\n"+ "\n"
+ body +"\\n";
}
上面就是完整的代码了,防止公司信息泄露,梦梦就把关键信息换成了文字代替。代码也是复制官网的,为什么还能出错,于是就开启了debug。
debug的时候,才发现原来是生成签名串部分写错了,多生成了一个“\n”。这才明白了,官网说的以“\n”结尾,不是看控制台打印出来的效果,我以为官网demo上的示例“\n”是idea的换行符,然后就再需要转义打印一个“\n”字符串,原来理解错了,debug的时候,发现就多了一个“\n”。
所以,以后建议小伙伴们,copy 官网代码的时候尽量不修改。