Java Исключение дешифрования AES: javax.crypto.BadPaddingException: - PullRequest
1 голос
/ 08 января 2020
    public static String encrypt(String strToEncrypt) {
        SecureRandom secureRandom = new SecureRandom();
        byte[] key = new byte[16];
        secureRandom.nextBytes(key);
        if (strToEncrypt != null) {
            try {
                IvParameterSpec ivspec = new IvParameterSpec(key);
                SecretKeySpec keySpec = new SecretKeySpec(Constants.secretKey.getBytes(Constants.UTF_8), Constants.AES);
                Cipher cipher = Cipher.getInstance(Constants.AES_CBC_PKCS5PADDING);
                cipher.init(Cipher.ENCRYPT_MODE, keySpec, ivspec);
                return Base64.getEncoder().encodeToString(cipher.doFinal(strToEncrypt.getBytes("UTF-8")));
            } catch (Exception ex) {
                LOGGER.error(CommonUtil.exceptionErrorPrefixSuffix("Encryption Exception in DoEncryption::encrypt", ex));
            }
        }
        return null;
    }

    public static String decrypt(String id) throws UnsupportedEncodingException {
        String decryptedId = null;
        SecureRandom secureRandom = new SecureRandom();
        byte[] key = new byte[16];
        secureRandom.nextBytes(key);
        SecretKeySpec keySpec = new SecretKeySpec(Constants.secretKey.getBytes(Constants.UTF_8),Constants.AES);
        byte[] decodedCiphertext = Base64.getDecoder().decode(id);
        try {
            IvParameterSpec ivspec = new IvParameterSpec(key);
            Cipher cipher = Cipher.getInstance(Constants.AES_CBC_PKCS5PADDING);
            cipher.init(Cipher.DECRYPT_MODE, keySpec , ivspec);
            byte[] original = cipher.doFinal(decodedCiphertext);
            decryptedId = new String(original);
            return decryptedId;
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        return null;
    }

Шифрование работает отлично. но во время расшифровки он выдает исключение.

javax.crypto.BadPaddingException: данный последний блок заполнен неправильно. Такие проблемы могут возникнуть, если во время расшифровки используется плохой ключ. at cipher.doFinal (decodedCiphertext);

Заранее спасибо.

Ответы [ 2 ]

1 голос
/ 08 января 2020

Вам необходимо использовать тот же Секретный ключ и тот же Вектор инициализации при расшифровке, который использовался для шифрования. Этот код использует другой случайный IV для шифрования, чем для дешифрования. Часто IV - это то, что может быть вычислено поэтапно обеими сторонами, или оно добавляется к зашифрованному сообщению, если это случайные байты, как в этом коде.

Вы можете повторно использовать ключ с течением времени, но вы должны не повторно использовать ключ и IV для нескольких сообщений. См. Для шифрования AES CB C, какое значение имеет шифрование IV? и AES, как транспортировать IV , с вопросами и ответами о векторе инициализации и дополнительной информацией о том, почему использовать фиксированный IV или повторно использовать IV и т. д.

Байты заполнения добавляются к сообщению (до шифрования), чтобы его длина была кратна размеру блока шифра (см. https://en.wikipedia.org/wiki/Padding_ (криптография) # PKCS # 5_and_PKCS # 7 , если интересно).

Когда байтовый массив дешифруется с использованием другого IV, дешифрованный текст не будет таким же, как открытый текст (по крайней мере, в первом блок). Если после расшифровки байты заполнения не совпадают (что может иметь место для короткого открытого текста), они не будут распознаваемы, и это приведет к BadPaddingException.

(в этом есть другая незначительная проблема code: он преобразует текст в байты для шифрования с использованием кодировки символов UTF-8, но преобразует дешифрованные байты обратно в текст, используя кодировку символов платформы по умолчанию, которая может быть не UTF-8. Что-то вроде decryptedId = new String(original, "UTF-8"); в decrypt метод будет одним из возможных исправлений.)

1 голос
/ 08 января 2020

Здесь проблема в том, что вы генерируете ключ случайным образом как в методе шифрования, так и в режиме дешифрования. Но поскольку вы используете алгоритм AES (алгоритм симметрии c), вы должны сохранять ключ одинаковым как для шифрования, так и для дешифрования.

...