Вопрос по encryption, java – Получение javax.crypto.IllegalBlockSizeException: длина ввода должна быть кратна 16 при расшифровке с использованием дополненного шифра?

16

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

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

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

Here is the code

 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);
}

}
Посмотрите мои ответы и получите некоторую идею. [Здесь тот же вопрос] [1] [1]:stackoverflow.com/questions/17234359/…    надеюсь, что это поможет. Krishna

Ваш Ответ

4   ответа
-1

Я бы предложил вместо работы со строками работать с самим байтом []. Я предполагаю, что некоторые байты изменяются, когда вы конвертируете его в строку. Следующий код работает для меня -

public static final String ENC_KEY = "abcdefghijklmnop";
public static final String DATA = "Hello World";

public static void test(){

    try {
        Cipher c = Cipher.getInstance("AES");

        SecretKeySpec secretKeySpec = new SecretKeySpec(ENC_KEY.getBytes("UTF-8"), "AES");

        c.init(Cipher.ENCRYPT_MODE, secretKeySpec);
        byte[] encBytes = c.doFinal(DATA.getBytes("UTF-8"));
        String encStr =  new String(encBytes, "UTF-8");
        System.out.println("Encrypted String: " + encStr);

        c.init(Cipher.DECRYPT_MODE, secretKeySpec);
        String decStr = new String(c.doFinal(encBytes),"UTF-8");
        System.out.println("Decrypted String: " + decStr);

    } catch (Exception ex) {
        System.out.println("Error in encrypting data");
        ex.printStackTrace();
    }
}

но если вы измените его на -

public static void test(){

    try {
        Cipher c = Cipher.getInstance("AES");

        SecretKeySpec secretKeySpec = new SecretKeySpec(ENC_KEY.getBytes("UTF-8"), "AES");

        c.init(Cipher.ENCRYPT_MODE, secretKeySpec);
        byte[] encBytes = c.doFinal(DATA.getBytes("UTF-8"));
        String encStr =  new String(encBytes, "UTF-8");
        System.out.println("Encrypted String: " + encStr);

        c.init(Cipher.DECRYPT_MODE, secretKeySpec);
        String decStr = new String(c.doFinal(encStr.getBytes("UTF-8")),"UTF-8");
        System.out.println("Decrypted String: " + decStr);

    } catch (Exception ex) {
        System.out.println("Error in encrypting data");
        ex.printStackTrace();
    }
}

Ты получишь

javax.crypto.IllegalBlockSizeException: Input length must be multiple of 16 when decrypting with padded cipher at com.sun.crypto.provider.CipherCore.doFinal(CipherCore.java:936) at com.sun.crypto.provider.CipherCore.doFinal(CipherCore.java:847) at com.sun.crypto.provider.AESCipher.engineDoFinal(AESCipher.java:446) at javax.crypto.Cipher.doFinal(Cipher.java:2164) at com.osfg.HelloWorld.test(HelloWorld.java:38) at com.osfg.HelloWorld.main(HelloWorld.java:22)

уведомление

String decStr = new String(c.doFinal(encBytes),"UTF-8");
VRS
String decStr = new String(c.doFinal(encStr.getBytes("UTF-8")),"UTF-8");
Error: User Rate Limit Exceeded
11

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

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

должно быть

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

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

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

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

Error: User Rate Limit Exceeded
Error: User Rate Limit Exceededstackoverflow.com/questions/10836902/…Error: User Rate Limit Exceeded M Sach
Error: User Rate Limit Exceeded
-3

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

Error: User Rate Limit Exceeded
-1

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

Похожие вопросы