微信支付专题——获取平台证书时生成签名的一个坑,报错401签名错误

        下载平台证书的时候,返回的状态码是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 官网代码的时候尽量不修改。
        

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

梦梦~~

你的鼓励是对我最大的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值