Как узнать, использую ли я правильную версию реализации алгоритма Triple Des?

Я искал в Интернете реализацию алгоритма Triple Des для Java.

Я нашел много решений и выбрал одно (с лучшей для меня документацией). Я протестировал и работает нормально.

Затем я искал реализацию алгоритма AES для Java. И нашел хорошие. Действительно похоже на реализацию алгоритма Triple Des, но не совсем то же самое.

Итак, я думаю, что добавить, если я использую реализацию алгоритма AES, но изменяю параметр экземпляра шифра с «AES» на «DESede»? Я внес изменения, проверил код и работал нормально. Но возвращаемая строка отличается от строки, возвращаемой в моей предыдущей реализации алгоритма Triple Des.

Итак, как говорится в заголовке, как мне узнать, использую ли я правильную версию реализации алгоритма Triple Des?

Это первая реализация:

public String encrypt(SecretKey key, String stringIn){

    String outString = "";      

    if (stringIn.isEmpty() || stringIn.toUpperCase().equals("NULL")){
        return "";
    }

    try {   

        if (key == null)
            key = this.key;


        InputStream in = new ByteArrayInputStream(stringIn.getBytes("UTF-8"));

        ByteArrayOutputStream out = new ByteArrayOutputStream();

        // Create and initialize the encryption engine
        Cipher cipher = Cipher.getInstance("DESede");
        cipher.init(Cipher.ENCRYPT_MODE, key);

        // Create a special output stream to do the work for us
        CipherOutputStream cos = new CipherOutputStream(out, cipher);

        // Read from the input and write to the encrypting output stream
        byte[] buffer = new byte[2048];

        int bytesRead;

        while ((bytesRead = in.read(buffer)) != -1) {
            cos.write(buffer, 0, bytesRead);
        }

        cos.close();

        // For extra security, don't leave any plaintext hanging around memory.
        java.util.Arrays.fill(buffer, (byte) 0);

        outString = out.toString();

    } catch (UnsupportedEncodingException e) {

        e.printStackTrace();

    } catch (NoSuchAlgorithmException e) {

        e.printStackTrace();

    } catch (NoSuchPaddingException e) {

        e.printStackTrace();

    } catch (InvalidKeyException e) {

        e.printStackTrace();

    } catch (IOException e) {

        e.printStackTrace();

    } finally {

        return outString;
    }

}

Это второй:

public String encrypt(SecretKey key, String stringIn){

    String outString = "";      

    if (stringIn.isEmpty() || stringIn.toUpperCase().equals("NULL")){
        return "";
    }


    try {   

        if (key == null)
            key = this.key;

        Cipher ecipher = Cipher.getInstance("DESede");

        ecipher.init(Cipher.ENCRYPT_MODE, key);

        byte[] bytes = stringIn.getBytes("UTF8");

        byte[] encVal = ecipher.doFinal(bytes);

        outString = new sun.misc.BASE64Encoder().encode(encVal);

    } catch (UnsupportedEncodingException e) {

        e.printStackTrace();

    } catch (NoSuchAlgorithmException e) {

        e.printStackTrace();

    } catch (NoSuchPaddingException e) {

        e.printStackTrace();

    } catch (InvalidKeyException e) {

        e.printStackTrace();

    } catch (IOException e) {

        e.printStackTrace();

    } finally {

        return outString;
    }

}

Это тестовый пример:

    String In: 6985475896580019
    String Returned when I Encripted with First code: Kœ¼i …€‡ä«‘]<žéù âpU
    String Returned when I Encripted with Second code: w1ujopasjH6ccFKgUtOgansFNBtxbWe8YwDhso2pZN8=

Извините за мой плохой английский.

Спасибо за вашу помощь


person Mark Comix    schedule 18.10.2012    source источник
comment
Итак, вы тоже тестировали расшифровку с обеими этими строками? У меня есть предчувствие, что первый код не сработает...   -  person eis    schedule 18.10.2012
comment
Да, оба работают нормально и возвращают одну и ту же исходную строку   -  person Mark Comix    schedule 18.10.2012
comment
Если вам нужен тот же результат, который у вас есть, вы используете ту же кодировку байтов зашифрованного текста. В первом вы используете метод toString() ByteArrayOutputStream, что не имеет смысла. Во втором вы используете кодировку base64, что имеет смысл. Другие советы: никогда не используйте значения по умолчанию, например Cipher.getInstance("DESede") использует режим по умолчанию и заполнение по умолчанию. Всегда явно указывайте оба. Всегда.   -  person President James K. Polk    schedule 18.10.2012
comment
@GregS Хорошо, отличная информация. Можете ли вы порекомендовать мне некоторые режимы и прокладки? Кроме того, вы думаете, что это хорошая идея использовать вариант 2? Спасибо.   -  person Mark Comix    schedule 18.10.2012


Ответы (1)


cipher.init(mode,key) генерирует случайный IV. На самом деле это самый безопасный способ его использования; вы должны использовать .getIV() и вернуть его с зашифрованным текстом (что также происходит автоматически; Java прикрепляет его к первым нескольким байтам криптопотока, именно так они расшифровывают OK). Различные IV изменяют результат точно так же, как и разные ключи, но он не обязательно должен быть секретным, он нужен только для того, чтобы идентичные вещи не шифровались одинаково.

Чтобы вызвать IV для сравнения алгоритмов или для расшифровки с известным, не включенным, используйте cipher.init(mode,key,new IvParameterSpec(iv))

person SilverbackNet    schedule 23.10.2012