Я пытаюсь зашифровать / расшифровать строки в python и java с помощью AES, и результат шифрования одинаков в обоих. Шифрование работает нормально, но когда я пытаюсь расшифровать строку в java, он показывает мне эту ошибку (javax.crypto.IllegalBlockSizeException: длина ввода должна быть кратна 16 при расшифровке с помощью дополненного шифра). В питоне все работает нормально. В чем проблема с расшифровкой java?
private static String toHexString(byte[] data) {
StringBuffer buf = new StringBuffer();
for (int i = 0; i < data.length; ++i) {
String s = Integer.toHexString(data[i] & 0XFF);
buf.append((s.length() == 1) ? ("0" + s) : s);
}
return buf.toString();
}
public static String encrypt(String input, String key) {
byte[] crypted = null;
try {
SecretKeySpec skey = new SecretKeySpec(key.getBytes(), "AES");
Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, skey);
crypted = cipher.doFinal(input.getBytes());
final String encryptedString = toHexString(Base64.encodeBase64(crypted));
return encryptedString;
} catch (Exception e) {
System.out.println(e.toString());
}
return "";
}
public static String decrypt(String encrypted, String key) {
char[] ch= encrypted.toCharArray();
try {
SecretKeySpec skeySpec = new SecretKeySpec(key.getBytes(), "AES");
Cipher cipher2 = Cipher.getInstance("AES/ECB/PKCS5Padding");
cipher2.init(Cipher.DECRYPT_MODE, skeySpec);
byte[] h =Hex.decodeHex(ch);
String de = new String(Base64.decodeBase64(cipher2.doFinal(Hex.decodeHex(ch))),"UTF-8");
return de;
} catch (Exception e) {
System.out.println(e.toString());
}
return null;
}
Почему вы используете и base64, и шестнадцатеричную кодировку? Я думал, этого будет достаточно
1. Как узнать "Шифрование работает нормально", если не удается его расшифровать? Отсутствие сообщения об ошибке не означает, что он работал правильно, как ожидалось. 2. javax.crypto.IllegalBlockSizeException означает, что данные для дешифрования имеют неправильный размер, он должен быть кратным 16 байтам. 3. Предоставьте тестовый ключ, данные и зашифрованные данные. 3. Лучше всего предположить, что существует несоответствие кодировки, см. Пункт 3 выше.
Не используйте режим ECB в новой работе и обновите устаревшую работу как можно скорее, это небезопасно, см. Режим ECB, прокрутите вниз до Penguin. Вместо этого используйте режим CBC со случайным IV, просто добавьте к зашифрованным данным префикс IV для использования при дешифровании, это не обязательно должно быть секретом.




Проще говоря, вы должны выполнять декодирование по базе 64 до расшифровки, а не после.
Вот пример, в котором зашифрованный текст закодирован по основанию 64. На самом деле нет причин выполнять шестнадцатеричное кодирование а также base 64, вы можете использовать любой из них, но использование обоих не имеет смысла.
Я использовал альтернативный кодек Base64, вы не указали, какой вы используете.
ПРЕДУПРЕЖДЕНИЕ: не копируйте код ниже, это небезопасно; он дает только ответ непосредственный на вопрос.
public static String encrypt(String input, String key) {
byte[] crypted = null;
try {
SecretKeySpec skey = new SecretKeySpec(key.getBytes(), "AES");
Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, skey);
crypted = cipher.doFinal(input.getBytes());
final String encryptedString = Base64.toBase64String(crypted);
return encryptedString;
} catch (Exception e) {
System.out.println(e.toString());
}
return "";
}
public static String decrypt(String encrypted, String key) {
// char[] ch= encrypted.toCharArray();
try {
SecretKeySpec skeySpec = new SecretKeySpec(key.getBytes(), "AES");
Cipher cipher2 = Cipher.getInstance("AES/ECB/PKCS5Padding");
cipher2.init(Cipher.DECRYPT_MODE, skeySpec);
// byte[] h = Hex.decode(encrypted);
String de = new String(cipher2.doFinal(Base64
.decode(encrypted)), "UTF-8");
return de;
} catch (Exception e) {
System.out.println(e.toString());
}
return null;
}
Я предполагаю, что это для учебных целей, поскольку с кодом много проблем, например. использование ключей в строках, шифрование в режиме ECB и т. д.
Хотя, вероятно, предпочтительнее не делать ничего из вышеперечисленного, но я оставлю краткий прямой ответ на этот вопрос.
Пожалуйста, покажите мне, как? я пытался сделать это но не получилось
Вам необходимо убедиться, что длина зашифрованных байтов одинакова как после шифрования, так и до дешифрования. Ошибка сообщает вам, что вы пытаетесь расшифровать массив байтов, длина которого не кратна шестнадцати. Что-то где-то либо теряет байты, либо прибавляет байты. Иногда обработка строк может добавлять нежелательные символы новой строки и тому подобное. Лучше всего проверить два байтовых массива побайтно, чтобы увидеть, где есть различия.