最近做了一个微信企业付款,即微信企业账户给用户下发红包的功能,从测试开始就出现偶发性的报SIGN_ERROR
签名错误,因为自己的项目比较多,就让同时帮忙debug排查了,排查的结果就是没问题,红包发放正常。
但是一上测试,就会偶发;
发现问题
无奈之下,我就把每次请求的request、response都打印出来了,通过微信支付接口签名校验工具测试了下,发现sign并不一致
发现一个问题,后面都一样,前面少0了,多验证几个签名错误的情况看看:
哦豁,还真是,对验证几个证实了这个问题,随意去检查生成sign的工具类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| public static String createSign(Map<String, String> parameters, String key) throws Exception {
ArrayList<String> keylist = new ArrayList<>(parameters.keySet()); Collections.sort(keylist); StringBuilder sb = new StringBuilder(); for (int i = 0; i < keylist.size(); i++) { if ("".equals(parameters.get(keylist.get(i)))) { continue; } sb.append(keylist.get(i)).append("=").append(parameters.get(keylist.get(i))); if (i < keylist.size() - 1) { sb.append("&"); } } sb = sb.append("&key=" + key); String sign = MD5Util.MD5(sb.toString()).toUpperCase(); return sign; }
|
发现问题
看了下,签名肯定没问题了,有问题就出在MD5咯?但是第一感觉是MD5会有啥问题,乍一看是没问题,很多人也是这么做的,但是如果得到的md5结果是以0开头的,那结果就悲剧了,转化为数值类型的时候会将开头的0丢弃,所以造成结果和sign不一致的情况出现!
如下就是我用的工具类
1 2 3 4 5 6 7 8 9 10 11 12 13
| static public String MD5(String str) { MessageDigest digest; try { digest = MessageDigest.getInstance("MD5"); digest.update(str.getBytes()); return new BigInteger(1, digest.digest()).toString(16); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); return null; } }
|
解决问题
改进后的
1 2 3 4 5 6 7 8 9
| static public String MD5(String str) throws Exception { java.security.MessageDigest md = MessageDigest.getInstance("MD5"); byte[] array = md.digest(str.getBytes("UTF-8")); StringBuilder sb = new StringBuilder(); for (byte item : array) { sb.append(Integer.toHexString((item & 0xFF) | 0x100).substring(1, 3)); } return sb.toString().toUpperCase(); }
|
如果您喜欢此博客或发现它对您有用,则欢迎对此发表评论。 也欢迎您共享此博客,以便更多人可以参与。 如果博客中使用的图像侵犯了您的版权,请与作者联系以将其删除。 谢谢 !