Подтвердить что ты не робот

Получение javax.crypto.IllegalBlockSizeException: длина ввода должна быть кратной 16 при расшифровке с дополненным шифрованием?

Используя tomcat, у меня есть два веб-приложения, например app1 и app2. Я отправил url из app1 в зашифрованном виде (используя код ниже) в app2. Затем в app2 Я расшифровал этот зашифрованный URL. Но я получаю ниже исключения по строке 50 метода decryp.

"Getting javax.crypto.IllegalBlockSizeException: Input length must be multiple of 16 when decrypting with padded cipher"

Хотя для отладки, когда я пытаюсь расшифровать (используя тот же код) зашифрованный url в app1, он отлично работает. Но не удалось выяснить, что вызывает это исключение в app2?

Вот код

 import java.security.Key;

 import javax.crypto.Cipher;
 import javax.crypto.spec.SecretKeySpec;

 import sun.misc.BASE64Decoder;
 import sun.misc.BASE64Encoder;

 public class AESEncryptionDecryptionTest {

   private static final String ALGORITHM       = "AES";
   private static final String myEncryptionKey = "ThisIsFoundation";
   private static final String UNICODE_FORMAT  = "UTF8";

   public static String encrypt(String valueToEnc) throws Exception {
      Key key = generateKey();
      Cipher c = Cipher.getInstance(ALGORITHM);
      c.init(Cipher.ENCRYPT_MODE, key);  
      byte[] encValue = c.doFinal(valueToEnc.getBytes());
      String encryptedValue = new BASE64Encoder().encode(encValue);
      return encryptedValue;
   }

public static String decrypt(String encryptedValue) throws Exception {
     Key key = generateKey();
     Cipher c = Cipher.getInstance(ALGORITHM);
     c.init(Cipher.DECRYPT_MODE, key);
     byte[] decordedValue = new BASE64Decoder().decodeBuffer(encryptedValue);
     byte[] decValue = c.doFinal(decordedValue);//////////LINE 50
     String decryptedValue = new String(decValue);
     return decryptedValue;
}

private static Key generateKey() throws Exception {
     byte[] keyAsBytes;
     keyAsBytes = myEncryptionKey.getBytes(UNICODE_FORMAT);
     Key key = new SecretKeySpec(keyAsBytes, ALGORITHM);
     return key;
}

public static void main(String[] args) throws Exception {

     String value = "password1";
     String valueEnc = AESEncryptionDecryptionTest.encrypt(value);
     String valueDec = AESEncryptionDecryptionTest.decrypt(valueEnc);

     System.out.println("Plain Text : " + value);
     System.out.println("Encrypted : " + valueEnc);
     System.out.println("Decrypted : " + valueDec);
}

}
4b9b3361

Ответ 1

Работает на моей машине. Помогает ли это, если вы используете `UNICODE_FORMAT 'в каждом случае, где вы преобразуете байты в строки и наоборот? Эта строка может быть проблемой:

byte[] encValue = c.doFinal(valueToEnc.getBytes()); 

должен быть

byte[] encValue = c.doFinal(valueToEnc.getBytes(UNICODE_FORMAT));

В любом случае, если вы используете "AES" в качестве алгоритма и используете JCE, используемым алгоритмом будет "AES/ECB/PKCS5Padding". Если вы на 100% не уверены в том, что делаете, ECB не должен использоваться ни для чего. Я бы рекомендовал всегда указывать алгоритм явно, чтобы избежать такой путаницы. "AES/CBC/PKCS5Padding" будет хорошим выбором. Но будьте осторожны, с любым разумным алгоритмом вы также должны будете обеспечить и управлять IV.

Использование шифрования ECB еще менее желательно в контексте шифрования паролей, что, как вы, кажется, делаете с вашим шифрованием, если я правильно интерпретирую ваш пример. Вы должны использовать шифрование на основе паролей, как указано в PKCS # 5 для этой цели, в Java это предусмотрено для вас в SecretKeyFactory. Обязательно используйте "PBKDF2WithHmacSHA1" с достаточно высоким количеством итераций (всего от ~ 5-20 000, зависит от вашей целевой машины) за использование паролей для получения симметричных ключей от них.

Тот же метод можно использовать, если на самом деле это парольная память, а не шифрование паролем, чего вы пытаетесь достичь.

Ответ 2

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

Ответ 3

Эта ошибка указывает, что вы использовали комбинацию выбора, которая требует только 16 символов исходного текста. Если вы хотите зашифровать пароль, вы можете обрезать или наложить исходный пароль на 16- char для шифрования и обрезать после дешифрования. Этот способ должен ограничивать реальный пароль не более 16- char, но вы можете использовать более длинный использованный пароль, чтобы смутить тех, кто не знает ваш пароль.