HMAC SHA256產生不同的結果,太坑了!!!
阿新 • • 發佈:2021-12-14
雖然這個坑是自己埋的,但還是要分享一波,一是給自己一個深刻的教訓,同時也是希望在茫茫人海中,如果你也遇到我同樣的問題,能夠減少彎路,少踩坑。
事情是這個樣子的,在一次簽名業務中,需要將簽名資料用對方簽名系統的祕鑰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
臥槽祕鑰中間幾個字串不一樣。於是呼果斷更改了測試環境配置,後面對接成功。回頭想想,還是粗心大意呀!!