[英]Decryption does not work on Production(Red Hat Enterprise Linux 7) and works on UAT(SUSE based linux distro)
我不建議使用DES進行加密/解密,但是使用的是舊代碼,因此我無法使用AES,現在我的代碼可以在具有生產db的本地環境(即mac)上正常工作,也可以在UAT上正常工作是基於SUSE的Linux發行版,但是解密在基於Redhat的生產環境下無法正常工作。 生產時,它拋出“輸入長度(帶填充),不是8字節的倍數”非法塊大小異常
@Service
public class EncryptionUtil {
private static final Logger log = LogManager.getLogger(EncryptionUtil.class);
@Autowired
GpsCacheManager gpsCacheManager;
private Cipher ecipher;
private Cipher dcipher;
@Autowired
private StringUtils stringUtils;
public EncryptionUtil() throws Exception {
ecipher = Cipher.getInstance("DES");
dcipher = Cipher.getInstance("DES");
initCipher();
}
private void initCipher() {
try {
String response = “[-3232, -34, -98, 111, -222, 33, -22, 55]”;
String[] byteValues = response.substring(1, response.length() - 1).split(",");
byte[] bytes = new byte[byteValues.length];
for (int i = 0, len = bytes.length; i < len; i++) {
bytes[i] = Byte.parseByte(byteValues[i].trim());
}
SecretKey key = new SecretKeySpec(bytes, "DES");
ecipher.init(Cipher.ENCRYPT_MODE, key);
dcipher.init(Cipher.DECRYPT_MODE, key);
} catch (Exception e) {
log.error(e.getMessage(), e);
}
}
public String encryptUTF8(String str) throws Exception {
// Encode the string into bytes using utf-8
byte[] utf8 = str.getBytes("UTF8");
// Encrypt
byte[] enc = ecipher.doFinal(utf8);
// Encode bytes to base64 to get a string
return new String(Base64.encodeBase64(enc));
}
public String decryptUTF8(String str) throws Exception {
if (stringUtils == null) {
stringUtils = new StringUtils();
}
//do not decrypt if a valid email.
if (stringUtils.isValidEmail(str)) {
return str;
}
// Decode base64 to get bytes
byte[] dec = Base64.decodeBase64(str.getBytes());
byte[] utf8 = null;
try {
utf8 = dcipher.doFinal(dec);
} catch (IllegalBlockSizeException e) {
return str;
}
// Decode using utf-8
return new String(utf8, "UTF8");
}
}
String.getBytes()
和new String(byte[])
,它們與平台有關,因此不應在此處使用。 同時,我用標准的Java的Base64替換了Base64類,該類旨在替代十年前的幾個Base64實現。
public String encryptUTF8(String str) throws Exception {
// Encode the string into bytes using utf-8
byte[] utf8 = str.getBytes(StandardCharsets.UTF_8);
// Encrypt
byte[] enc = ecipher.doFinal(utf8);
// Encode bytes to base64 to get a string
return Base64.getEncoder().encodeToString(enc));
//Old class: return new String(Base64.encodeBase64(enc), StandardCharsets.US_ASCII);
}
public String decryptUTF8(String str) throws Exception {
if (stringUtils == null) {
stringUtils = new StringUtils();
}
//do not decrypt if a valid email.
if (stringUtils.isValidEmail(str)) {
return str;
}
// Decode base64 to get bytes
//byte[] dec = Base64.getDecoder().decode(str.getBytes(StandardCharsets.US_ASCII));
byte[] dec = Base64.getDecoder().decode(str);
try {
byte[] utf8 = dcipher.doFinal(dec);
// Decode using utf-8
return new String(utf8, StandardCharsets.UTF_8);
} catch (IllegalBlockSizeException e) {
return str;
}
}
有一個問題: String
用於Unicode文本,帶有兩個字節的char
(UTF-16)。 這意味着任何byte[]
值都必須是某種編碼的文本,並且該編碼必須轉換為String。 任何任意的byte[]
值都不是有效的String。 尤其是在具有卓越的UTF-8編碼的Linux上,它將破壞數據。
問題可能出在decryptUTF8
。 如果在原始代碼中默認編碼為單字節編碼,則所有內容均被原樣吞下。 對於Linux,UTF-8可能會遇到錯誤的UTF-8多字節序列。 或編碼為7位ASCII。
通常,將String
和byte[]
分開; 使用byte[]
表示非文本二進制數據。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.