HMACSHA256计算后产生不同的结果,太坑了!!!

     虽然这个坑是自己埋的,但还是要分享一波,一是给自己一个深刻的教训,同时也是希望在茫茫人海中,如果你也遇到我同样的问题,能够减少弯路,少踩坑。

     事情是这个样子的,在一次签名业务中,需要将签名数据用对方签名系统的秘钥secret,进行HmacSHA256计算。 本地调通以后,部署测试环境后,却发现始终无法签名成功。

发现是因为本地和测试环境HmacSHA256计算结果不同导致。代码如下面所示:

 1  /***
 2      * 计算请求签名值
 3      *
 4      * @param message 待计算的消息
 5      * @param secret 密钥
 6      * @return HmacSHA256计算后摘要值的Base64编码
 7      * @throws Exception 加密过程中的异常信息
 8      */
 9     public static String doSignatureBase64(String message, String secret) throws Exception {
10         final String algorithm = "HmacSHA256";
11         Mac hmacSha256;
12         String digestBase64 = null;
13         try {
14             hmacSha256 = javax.crypto.Mac.getInstance(algorithm);
15             byte[] keyBytes = secret.getBytes("UTF-8");
16             byte[] messageBytes = message.getBytes("UTF-8");
17             hmacSha256.init(new SecretKeySpec(keyBytes, 0, keyBytes.length, algorithm));
18             // 使用HmacSHA256对二进制数据消息Bytes计算摘要
19             byte[] digestBytes = hmacSha256.doFinal(messageBytes);
20             // 把摘要后的结果digestBytes转换成十六进制的字符串
21             // String digestBase64 = Hex.encodeHexString(digestBytes);
22             // 把摘要后的结果digestBytes使用Base64进行编码
23             digestBase64 = new String(Base64.encodeBase64(digestBytes), "UTF-8");
24         } catch (NoSuchAlgorithmException e) {
25             String msg = MessageFormat.format("不支持此算法: {0}", e.getMessage());
26             Exception ex = new Exception(msg);
27             ex.initCause(e);
28             throw ex;
29         } catch (UnsupportedEncodingException e) {
30             String msg = MessageFormat.format("不支持的字符编码: {0}", e.getMessage());
31             Exception ex = new Exception(msg);
32             ex.initCause(e);
33             throw ex;
34         } catch (InvalidKeyException e) {
35             String msg = MessageFormat.format("无效的密钥规范: {0}", e.getMessage());
36             Exception ex = new Exception(msg);
37             ex.initCause(e);
38             throw ex;
39         }
40         return digestBase64;
41     }

        然后开始百度,寻找度娘,看各种资料,网上针对此原因的回复,总结了一下,基本是以下几种原因:

       1.获取秘钥secret、加密内容message二进制时没有指定编码,显然代码已指定 UTF-8编码,此种情况排除;

       2.加密内容message含有"/n"特殊字符等导致。 这里我message故意传入了数字字符串,即message=“123”。此种情况也排除;

       3.本地tomcate、JDK版本问题,后面经过验证也排除了;

       4.秘钥本地与测试环境不同。但是我眨眼一看秘钥,测试环境:b579053cagcb421cae82751cb8c7a091、本地环境: b5790530f85b431cae8275a3b8c7a091。一样啊。

       所以百思不得其解。 那问题究竟在哪呢?我刚说了,我是眨眼一看,作为程序员,需要的是严谨细致,你以为的一样,我们在这样对比下呢?

       测试环境 b579053cagcb421cae82751cb8c7a091

       本地环境:b5790530f85b431cae8275a3b8c7a091

       卧槽秘钥中间几个字符串不一样。于是呼果断更改了测试环境配置,后面对接成功。回头想想,还是粗心大意呀!!

 

 

     

posted @ 2021-12-14 20:40  灰太狼小试牛刀  阅读(3649)  评论(0编辑  收藏  举报