收藏
回答

Http头Authorization值格式错误,请参考《微信支付商户REST API签名规则》?

按照官方文档https://pay.weixin.qq.com/wiki/doc/apiv3/wechatpay/wechatpay4_0.shtml的步骤, 获取签名时,依然报 ‘Http头Authorization值格式错误,请参考《微信支付商户REST API签名规则》’。但是我觉得最离谱的是,把官网的命令复制下来执行后,依然报此错误,按理说是报数据错误,各非格式问题。有人员能解答一下吗?

以下是获取签名信息的代码,同样也是官方给的示例代码:

public static void main(String[]args) throws Exception {
    //认证类型
    String schema = "WECHATPAY2-SHA256-RSA2048";
    String httpurl = "/v3/certificates";
    String httpAuthorization = getAuthorization("GET", httpurl, "");
    String curl = "curl https://api.mch.weixin.qq.com/v3/certificates -H 'Authorization: WECHATPAY2-SHA256-RSA2048 " + httpAuthorization + "'";
    System.out.println(curl);
}
/**
 * 得到签名信息
 * @param method
 * @param url
 * @param body
 * @return
 * @throws Exception
 */
public static String getAuthorization(String method, String url, String body) throws Exception {
    String nonceStr = StrUtil.generateNonceStr();
    long timestamp = System.currentTimeMillis() / 1000;
    //获取签名串
    String message = buildMessage(method, url, timestamp, nonceStr, body);
    System.out.println("签名串:"+message);
    //得到签名
    String signature = sign(message.getBytes("utf-8"));
    System.out.println("签名值:"+signature);
    //五项签名信息,无顺序要求
    String httpAuthorization = "mchid=\"" + MCHID_JDKJ + "\","
            + "nonce_str=\"" + nonceStr + "\","
            + "signature=\"" + signature + "\","
            + "timestamp=\"" + timestamp + "\","
            + "serial_no=\"" + MCHSERIALNO_JDKJ + "\""
            ;
    System.out.println("httpAuthorization:" + httpAuthorization);
    return httpAuthorization;
}
/**
 * 获取签名值
 * @param message
 * @return
 * @throws Exception
 */
public static String sign(byte[] message) throws Exception {
    Signature sign = Signature.getInstance("SHA256withRSA");
    //# 示例:私钥存储在文件
//        PrivateKey merchantPrivateKey = PemUtil.loadPrivateKey(new FileInputStream("D:\\test\\apiclient_key.pem"));
    PrivateKey merchantPrivateKey = getPrivateKey("D:\\test\\apiclient_key.pem");
    sign.initSign(merchantPrivateKey);
    sign.update(message);
    return Base64.getEncoder().encodeToString(sign.sign());
}
/**
 * 获取私钥。
 * @param filename 私钥文件路径  (required)
 * @return 私钥对象
 */
public static PrivateKey getPrivateKey(String filename) throws IOException {
String content = new String(Files.readAllBytes(Paths.get(filename)), "utf-8");
    try {
        String privateKey = content.replace("-----BEGIN PRIVATE KEY-----", "")
                .replace("-----END PRIVATE KEY-----", "")
                .replaceAll("\\s+", "");
        KeyFactory kf = KeyFactory.getInstance("RSA");
        return kf.generatePrivate(
                new PKCS8EncodedKeySpec(Base64.getDecoder().decode(privateKey)));
    } catch (NoSuchAlgorithmException e) {
        throw new RuntimeException("当前Java环境不支持RSA", e);
    } catch (InvalidKeySpecException e) {
        throw new RuntimeException("无效的密钥格式");
    }
}
/**
 * 构造签名串
 * 签名串一共有五行,每一行为一个参数。行尾以 \n(换行符,ASCII编码值为0x0A)结束,包括最后一行。如果参数本身以\n结束,也需要附加一个\n
 * HTTP请求方法\n
 * URL\n
 * 请求时间戳\n
 * 请求随机串\n
 * 请求报文主体\n
 * @param method
 * @param url
 * @param timestamp
 * @param nonceStr
 * @param body
 * @return
 * @throws Exception
 */
public static String buildMessage(String method, String url, long timestamp, String nonceStr, String body) {
    return method + "\n"
            + url + "\n"
            + timestamp + "\n"
            + nonceStr + "\n"
            + body + "\n";
}

最后生成的签名信息如下:

最后使用命令执行结果如下:

请问这是哪里的问题

回答关注问题邀请回答
收藏

1 个回答

登录 后发表内容