簡體   English   中英

解密在正式版(Red Hat Enterprise Linux 7)上不起作用,而在UAT(基於SUSE的Linux發行版)上起作用

[英]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。

通常,將Stringbyte[]分開; 使用byte[]表示非文本二進制數據。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM