Неверная длина зашифрованного текста при использовании 3DESede с заполнением PKS5 javax.crypto

Я использую следующий код в своем приложении для Android, чтобы зашифровать строку в Triple DES с помощью < em> Режим зашифрованной кодовой книги (ECB) с тремя независимыми ключами (также известными как 3DESede), которые предоставляются в виде массива ключей размером 24 байта. Поэтому я использую Java Crypto API. Это работает довольно хорошо, но если я зашифрую строку из восьми символов, я получу 16-байтовый зашифрованный текст, чего не должно происходить, поскольку 3DES работает с фрагментами по 64 бита (соответственно 8 байтов). То же самое справедливо и для заполнения PKCS5, так как это также работает с фрагментами 64-бит. Итак, мой вопрос: что вызывает эту проблему?

private static byte[] encryptText(String plaintext, byte[] keyBytes) throws Exception {
    // Get plaintext as ASCII byte array
    final byte[] plainBytes;
    if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.KITKAT) {
        plainBytes = plaintext.getBytes(StandardCharsets.US_ASCII);
    } else {
        plainBytes = plaintext.getBytes("US-ASCII");
    }

    // Generate triple DES key from byte array
    final DESedeKeySpec keySpec = new DESedeKeySpec(keyBytes);
    SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DESede");
    SecretKey key = keyFactory.generateSecret(keySpec);

    // Setup the cipher
    final Cipher c3des = Cipher.getInstance("DESede/ECB/PKCS5Padding");
    c3des.init(Cipher.ENCRYPT_MODE, key);

    // Return ciphertext
    return c3des.doFinal(plainBytes);
}

person Phidelux    schedule 14.02.2017    source источник
comment
1. Лучше не использовать 3DES в новом коде, AES - это текущий стандарт симметричного шифрования. 2. Не используйте режим ECB, это небезопасно, см. режим ECB прокрутите вниз до Пингвина. Вместо этого используйте режим CBC со случайным IV, просто добавьте к зашифрованным данным префикс IV для использования при расшифровке, это не нужно не секретировать. 3. Шифрование - это просто, а безопасность использования - сложная задача.   -  person zaph    schedule 14.02.2017


Ответы (2)


PKCS5Padding добавляет 1–8 байтов заполнения при использовании с DES. Если вы зашифруете 8 байтов, вы получите 8 дополнительных байтов заполнения, чтобы получить четное количество блоков.

Если вы использовали Cipher.getInstance("DES/ECB/NoPadding") и зашифровали 8 байтов, вы получите 8 байтов зашифрованного текста.

person Ebbe M. Pedersen    schedule 14.02.2017

Когда используется заполнение PKCS # 5, оно всегда должно добавлять заполнение, иначе при расшифровке не будет способа определить, было ли добавлено заполнение. Таким образом, даже если входные данные в точности кратны размеру блока, необходимо добавить заполнение, и это будет 8 байтов.

См. Заполнение PKCS:

Если исходные данные являются целым числом, кратным N байтам, то добавляется дополнительный блок байтов со значением N. Это необходимо для того, чтобы алгоритм дешифрования мог с уверенностью определить, является ли последний байт последнего блока байтом заполнения, указывающим количество добавленных байтов заполнения, или частью сообщения открытого текста. Рассмотрим сообщение с открытым текстом, которое является целым числом, кратным N байтам, причем последний байт открытого текста равен 01. Без дополнительной информации алгоритм дешифрования не сможет определить, является ли последний байт байтом открытого текста или байтом заполнения. Однако, добавляя N байтов значения N после байта открытого текста 01, алгоритм дешифрования всегда может обрабатывать последний байт как вспомогательный байт и удалять соответствующее количество вспомогательных байтов из конца зашифрованного текста; указанное количество удаляемых байтов основано на значении последнего байта.

Заполнение PKCS # 5 идентично заполнению PKCS # 7, за исключением того, что оно было определено только для блочных шифров, которые используют размер блока 64-бит (8 байт). На практике они могут использоваться как взаимозаменяемые.

person zaph    schedule 14.02.2017