首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計綜合問答

Java RSA 驗證/解密失敗?罪魁禍首是 byte[] 轉 String 時的 UTF-8 編碼陷阱

     編輯:程式設計綜合問答

跨服務傳遞加密數據,本地驗證通過,遠端卻失敗。根因在於 byte[] 與 String 互轉時,預設 UTF-8 將單字節誤判為多字節字符,導致數據損壞。

典型錯誤流程

  1. 私鑰加密 → byte[] cipher。
  2. 錯誤寫法:String s = new String(cipher); 或 new String(cipher, "UTF-8")。
  3. 網路傳輸(JSON、表單) → 對端收到 String。
  4. 對端還原:byte[] recv = s.getBytes("UTF-8") → 數據長度、內容已變,解密/驗簽必敗。

正確處理方案

方案一:Base64 編碼(推薦,最通用)

// 加密端
String encoded = Base64.getEncoder().encodeToString(cipher);
// 傳輸 encoded 字符串

// 解密端
byte[] cipher = Base64.getDecoder().decode(encoded);

方案二:Hex 編碼

// 加密端
String hex = bytesToHex(cipher); // 自行實現或用 Apache Commons Codec
// 解密端
byte[] cipher = hexToBytes(hex);

核心原則

加密輸出的 byte[] 必須經過「二進制安全」編碼才能當作字符串傳輸。UTF-8 是字符編碼,不適合任意二進制數據。

驗證代碼片段

// 簽名驗證
boolean ok = RSAUtils.verify(plainBytes, publicKey, signatureBytes);
// 解密
byte[] plain = RSAUtils.decrypt(cipherBytes, privateKey);

修正編碼後,控制台打印的 Arrays.equals(localBytes, remoteBytes) 應為 true,驗證與解密均恢復正常。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved