CryptoJS Triple DES-код в Java-эквивалент - PullRequest
0 голосов
/ 12 мая 2019

У меня есть следующий код CryptoJS для шифрования и дешифрования.

Код шифрования

<script type="text/javascript">
    $(document).on("click", "#crack", function(evt) {
        evt.preventDefault();
        var e = $("#plaintext").val();
        var key = $("#key").val();
        var iv = CryptoJS.enc.Utf8.parse(key);
        var r, t = CryptoJS.enc.Utf8.parse(key), // key
            n = CryptoJS.DES.encrypt(CryptoJS.enc.Utf8.parse(e), t,{
                iv:iv,
                mode: CryptoJS.mode.ECB,
                padding: CryptoJS.pad.Pkcs7
            });
            r = n.toString(CryptoJS.enc.Utf8);
        $(".result").text(n);
    });
    </script>

Код расшифровки

<script type="text/javascript">
    $(document).on("click", "#crack", function(evt) {
        evt.preventDefault();
        var e = $("#ciphertext").val();

        var key = $("#key").val();
        var r, t = CryptoJS.enc.Utf8.parse(key), // key
            n = CryptoJS.DES.decrypt({
                ciphertext: CryptoJS.enc.Base64.parse(e.replace('"', ""))
            }, t, {
                mode: CryptoJS.mode.ECB,
                padding: CryptoJS.pad.Pkcs7
            }),
            r = n.toString(CryptoJS.enc.Utf8);
        $(".result").text(r);
    });
    </script>

Я хочу воссоздать ту же логику в Java, но она работает не совсем хорошо. Я следил за большинством существующих вопросов, которые уже задавались здесь на StackOverflow, но это не помогло.

Я нашел другую статью и пример кода, который, казалось, будет работать, но это не так.

Ссылка на статью: https://androidfreetutorial.wordpress.com/2017/03/14/android-encryptiondecryption-with-tripledes-3des-algorithm/

Я получаю следующее сообщение об ошибке:

java.security.NoSuchAlgorithmException: Cannot find any provider supporting DESede/ECB/PKCS7Padding

Что я делаю не так, и чем код CryptoJS здесь отличается от кода Java?

Примеры входов:

Ключ:

CipherText: 3OwGE1y7zFLyPT49uGMvFQ ==

Ключ: 75a1b1ae20af8de7bdfb6fac8ca9d36c0ab91930


РЕДАКТИРОВАТЬ: Добавлен рабочий код. Также CryptoJS - это Simple DES, а не Triple DES, как предложено @James приложение, которое я тестировал, использовало tripledes.js в файле ресурсов, что заставило меня поверить, что, возможно, Triple DES используется. Я проверял, что в CryptoJS, если вы хотите использовать TripleDES, вы должны использовать что-то вроде CryptoJS.TripleDES.encrypt(...). Кроме того, я забыл, что размер ключа DES равен 8 байтам, и ключ, который я дал, не был обработан должным образом, что вызвало исключение неправильного заполнения, которое я обошел с помощью Arrays.copyOf, и, наконец, благодаря P.Soutzikevich.

Следующий код работает именно так, как я хочу.

private final int DES_KEY_SIZE = 8;
private final String DES_MODE = "DES/ECB/PKCS5Padding";

Шифрование

byte[] keyBytes = Arrays.copyOf(secretKey.getBytes(), DES_KEY_SIZE);
byte[] plainTextBytes = plainText.getBytes();
desKeySpec = new SecretKeySpec(keyBytes, "DES");
desCipher = Cipher.getInstance(DES_MODE);
desCipher.init(Cipher.ENCRYPT_MODE, desKeySpec);
byte[] encryptedText = desCipher.doFinal(plainTextBytes);
data = Base64.getEncoder().encodeToString(encryptedText);

дешифрование:

byte[] keyBytes = Arrays.copyOf(secretKey.getBytes(), DES_KEY_SIZE);
byte[] encryptedTextBytes = Base64.getDecoder().decode(cipherText);
desKeySpec = new SecretKeySpec(keyBytes, "DES");
desCipher = Cipher.getInstance(DES_MODE);
desCipher.init(Cipher.DECRYPT_MODE, desKeySpec);
data = new String(desCipher.doFinal(encryptedTextBytes));

1 Ответ

1 голос
/ 12 мая 2019

Преобразование, которое вы использовали, похоже, недопустимо для Triple-DES.

Изменить отступ этой строки:

public static String ALGO = "DESede/ECB/PKCS7Padding";

в PKCS5Padding :

public static String ALGO = "DESede/ECB/PKCS5Padding";

Полученное вами сообщение об ошибке компилятора было довольно ясным; Нет, исключение для такого алгоритма . Компиляторы обычно страдают от плохих сообщений с описанием ошибок, но в этом случае они указывают непосредственно на источник ошибки. Сделав небольшой старый добрый веб-поиск, вы бы поняли, что Triple DES принимает заполнение PKCS 5 или вообще без заполнения.

Где я получил эту информацию? Из документации конечно.

Смотрите этот скриншот: enter image description here

Документацию по объекту java Cipher можно найти здесь . Вы можете видеть, что один из параметров для вызова Cipher.init(int opmode, Key key), очевидно, имеет тип Key.

Нажав на соответствующую ссылку, чтобы прочитать об интерфейсе Key, вы заметите, что один из реализующих Классов (этого интерфейса) - SecretKeySpec. Документацию для SecretKeySpec можно найти здесь .

Из первого абзаца SecretKeySpec:

Этот класс полезен только для необработанных секретных ключей, которые могут быть представлены в виде байтового массива и с которыми не связаны никакие параметры ключа, например, DES или Triple DES ключи.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...