Расшифровка не работает в Production (Red Hat Enterprise Linux 7) и работает в UAT (дистрибутив Linux на основе SUSE) - PullRequest
0 голосов
/ 27 июня 2019

Я использую DES для шифрования / дешифрования, так как это не рекомендуется, но это старый код, поэтому я не могу перейти на AES, теперь мой код работает нормально в локальной среде (например, mac) с производственной базой данных, также работает нормальнона UAT, который является дистрибутивом Linux, основанным на SUSE, но дешифрование не работает на Production, основанном на 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");
    }
}

1 Ответ

1 голос
/ 27 июня 2019

Существует проблема с String.getBytes() и new String(byte[]), которые зависят от платформы и не должны использоваться здесь. В то же время я заменил этот класс Base64 стандартным java 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 s (UTF-16). Это означает, что любое значение byte[] должно быть текстом в некоторой кодировке, и эта кодировка должна быть преобразована в строку. Любое произвольное значение byte[] не будет допустимой строкой. Особенно в Linux с выдающейся кодировкой UTF-8, которая будет повреждать данные.

Проблема, вероятно, заключается в decryptUTF8. Если в исходном коде кодировкой по умолчанию является однобайтовая кодировка, все проглатывается как есть. Для Linux, UTF-8, могут встречаться ошибочные многобайтовые последовательности UTF-8. Или кодировка 7-битная ASCII.

В целом держите String и byte[] на расстоянии; используйте byte[] для нетекстовых двоичных данных.

...