Шифрование / дешифрование на Java и python с использованием AES

Я пытаюсь зашифровать / расшифровать строки в 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;
}

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

rossum 29.03.2018 00:44

Почему вы используете и base64, и шестнадцатеричную кодировку? Я думал, этого будет достаточно

slipperyseal 29.03.2018 00:54

1. Как узнать "Шифрование работает нормально", если не удается его расшифровать? Отсутствие сообщения об ошибке не означает, что он работал правильно, как ожидалось. 2. javax.crypto.IllegalBlockSizeException означает, что данные для дешифрования имеют неправильный размер, он должен быть кратным 16 байтам. 3. Предоставьте тестовый ключ, данные и зашифрованные данные. 3. Лучше всего предположить, что существует несоответствие кодировки, см. Пункт 3 выше.

zaph 29.03.2018 02:30

Не используйте режим ECB в новой работе и обновите устаревшую работу как можно скорее, это небезопасно, см. Режим ECB, прокрутите вниз до Penguin. Вместо этого используйте режим CBC со случайным IV, просто добавьте к зашифрованным данным префикс IV для использования при дешифровании, это не обязательно должно быть секретом.

zaph 29.03.2018 02:33
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
1
4
741
1

Ответы 1

Проще говоря, вы должны выполнять декодирование по базе 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 и т. д.

Хотя, вероятно, предпочтительнее не делать ничего из вышеперечисленного, но я оставлю краткий прямой ответ на этот вопрос.

Maarten Bodewes 29.03.2018 03:05

Пожалуйста, покажите мне, как? я пытался сделать это но не получилось

L.. 07.04.2018 21:05

Другие вопросы по теме