Выход в режиме CFB совпадает с выходом CTR; Я делаю что-то неправильно? - PullRequest
0 голосов
/ 28 июня 2018

Я пытался сравнить режимы шифрования с использованием AES и заметил, что мой вывод CFB такой же, как мой вывод CTR. Я делаю что-то не так или это должно произойти? Моя функция шифрования CTR идентична функции CFB ниже, за исключением строки «AES / CTR / NoPadding» в качестве аргумента для Cipher.getInstance (). Спасибо!

try {
        // Dernier exemple CTR mode
        // Clé 16 bits
        byte[] keyBytes = new byte[]{(byte) 0x36, (byte) 0xf1, (byte) 0x83,
                (byte) 0x57, (byte) 0xbe, (byte) 0x4d, (byte) 0xbd,
                (byte) 0x77, (byte) 0xf0, (byte) 0x50, (byte) 0x51,
                (byte) 0x5c, 0x73, (byte) 0xfc, (byte) 0xf9, (byte) 0xf2};
        // IV 16 bits (préfixe du cipherText)
        byte[] ivBytes = new byte[]{(byte) 0x69, (byte) 0xdd, (byte) 0xa8,
                (byte) 0x45, (byte) 0x5c, (byte) 0x7d, (byte) 0xd4,
                (byte) 0x25, (byte) 0x4b, (byte) 0xf3, (byte) 0x53,
                (byte) 0xb7, (byte) 0x73, (byte) 0x30, (byte) 0x4e, (byte) 0xec};

        // Initialisation
        SecretKeySpec key = new SecretKeySpec(keyBytes, "AES");
        IvParameterSpec ivSpec = new IvParameterSpec(ivBytes);

        // Mode
        Cipher cipher = Cipher.getInstance("AES/CFB/PKCS5Padding");

        String originalText = "hello i am original";
        // ///////////////////////////////ENCRYPTING
        cipher.init(Cipher.ENCRYPT_MODE, key, ivSpec);
        ciphered = cipher.doFinal(originalText.getBytes());
        String cipherText = new String(ciphered, "UTF-8");
        System.out.println("ciphered: " + cipherText);
        // ///////////////////////////////DECRYPTING
        cipher = Cipher.getInstance("AES/CFB/PKCS5Padding");

        cipher.init(Cipher.DECRYPT_MODE , key, ivSpec);
        byte[] plain = cipher.doFinal(ciphered);
        originalText = new String(plain, "UTF-8");
        System.out.println("plaintext: " + originalText);
    }
    catch (Exception e){

    }

1 Ответ

0 голосов
/ 29 июня 2018

CFB (Cipher Feedback) * Режим 1002 * и CTR (Счетчик) * Режим 1004 * оба являются режимами работы , которые определяют, как использовать базовый блочный примитив (в данном случае AES) для шифрования и дешифрования последовательностей байтов.

Однако самый первый блок (в данном случае 16 байт) заканчивается шифрованием идентичным образом. Вот схема режима CTR из Wikipedia : CTR mode

и вот схема режима CFB, также из Wikipedia :

CFB mode

Фокусируясь на крайнем левом блоке, вы можете видеть, что они выдают одинаковый выходной сигнал в обоих случаях, если IV в режиме CFB совпадает с значением Nonce / Counter в режиме CTR.

Вот небольшая модификация вашего кода, которая показывает различия в шифровании hello i am original в двух режимах.

import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import javax.xml.bind.DatatypeConverter;

class Main {

    public static void main(String[] args) throws Exception {
        // Dernier exemple CTR mode
        // Clé 16 bits
        byte[] keyBytes = new byte[]{(byte) 0x36, (byte) 0xf1, (byte) 0x83,
                (byte) 0x57, (byte) 0xbe, (byte) 0x4d, (byte) 0xbd,
                (byte) 0x77, (byte) 0xf0, (byte) 0x50, (byte) 0x51,
                (byte) 0x5c, 0x73, (byte) 0xfc, (byte) 0xf9, (byte) 0xf2};
        // IV 16 bits (préfixe du cipherText)
        byte[] ivBytes = new byte[]{(byte) 0x69, (byte) 0xdd, (byte) 0xa8,
                (byte) 0x45, (byte) 0x5c, (byte) 0x7d, (byte) 0xd4,
                (byte) 0x25, (byte) 0x4b, (byte) 0xf3, (byte) 0x53,
                (byte) 0xb7, (byte) 0x73, (byte) 0x30, (byte) 0x4e, (byte) 0xec};

        // Initialisation
        SecretKeySpec key = new SecretKeySpec(keyBytes, "AES");
        IvParameterSpec ivSpec = new IvParameterSpec(ivBytes);

        // Mode
        Cipher cipher = Cipher.getInstance("AES/CFB/PKCS5Padding");

        String originalText = "hello i am original";
        // ///////////////////////////////ENCRYPTING
        cipher.init(Cipher.ENCRYPT_MODE, key, ivSpec);
        byte[] ciphered = cipher.doFinal(originalText.getBytes());
//            String cipherText = new String(ciphered, "UTF-8");
        System.out.println("CFB: " + DatatypeConverter.printHexBinary(ciphered));

        // CTR mode
        cipher = Cipher.getInstance("AES/CTR/NoPadding");
        cipher.init(Cipher.ENCRYPT_MODE, key, ivSpec);
        ciphered = cipher.doFinal(originalText.getBytes());
        System.out.println("CTR: " + DatatypeConverter.printHexBinary(ciphered));

    }
}

и вывод:

CFB: 25F64E6F324681A2B6534807BAFB11C52C0F9BBD28BE2032915EB423B1E0B415
CTR: 25F64E6F324681A2B6534807BAFB11C59390BE

Режим CTR в основном превращает блочный шифр в байт-ориентированный потоковый шифр, поэтому длина зашифрованного текста такая же, как и у открытого текста. Это также означает, что злоумышленнику относительно легко изменить зашифрованный текст, чтобы вызвать предсказуемые изменения в дешифрованном открытом тексте. По этой причине вы должны использовать MAC для обнаружения любых изменений в шифре, например, HMAC. Современным выбором является AES-GCM, который представляет собой режим, подобный счетчику, который также включает встроенный MAC.

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