引言
在和银行进行数据传输的时候, 签名采用了参数MD5的方式,具体做法参考我的博客《请求参数按照ASCII码从小到大排序后追加秘钥再进行加密得到签名值》
由于在和行内进行交互的时候,起作用的一些 接口并没有采用验签的环节,所以签名的问题也一直没有暴露 出来,最近要上一个新接口,需要用到签名,在进行批量测试的时候,有些数据签名验证失败,而大部分数据是可以验签成功的, 这让我一时半会有些不解啊,最后我对比成功和失败的签名发现,失败的签名竟然只有31位,而MD5 一般是16位或者32位,那么问题肯定是出现在工具类代码上。
原始代码,bug代码:
/** * 对字符串进行MD5加密 * * @param str 需要加密的字符串 * @return 小写MD5字符串 32位 */ 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; }
上面代码有bug是因为,在转换成字符串的时候,如果首位是两个0,这会 只保留一位数,这就导致生成的MD5只有31位。
正确代码:
public static String toMd5(String str) { String re = null; byte encrypt[]; try { byte[] tem = str.getBytes(); MessageDigest md5 = MessageDigest.getInstance("md5"); md5.reset(); md5.update(tem); encrypt = md5.digest(); StringBuilder sb = new StringBuilder(); for (byte t : encrypt) { String s = Integer.toHexString(t & 0xFF); if (s.length() == 1) { s = "0" + s; } sb.append(s); } re = sb.toString(); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } return re; }