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

本文阅读 2 分钟
首页 代码,Java 正文

        下载平台证书的时候,返回的状态码是401,错误信息如下图所示:

img         可以看到错误信息提示是错误的签名,于是就检查关于签名部分的代码,下面是从官网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。 img

        debug的时候,才发现原来是生成签名串部分写错了,多生成了一个“n”。这才明白了,官网说的以“n”结尾,不是看控制台打印出来的效果,我以为官网demo上的示例“n”是idea的换行符,然后就再需要转义打印一个“n”字符串,原来理解错了,debug的时候,发现就多了一个“n”。 img

        所以,以后建议小伙伴们,copy 官网代码的时候尽量不修改。         

本文为互联网自动采集或经作者授权后发布,本文观点不代表立场,若侵权下架请联系我们删帖处理!文章出自:https://blog.csdn.net/qq_46540738/article/details/122361106
-- 展开阅读全文 --
安全面试之XSS(跨站脚本攻击)
« 上一篇 07-24

发表评论

成为第一个评论的人

热门文章

标签TAG

最近回复