Код не работает для расшифровки без соли или iv в Java

У меня есть зашифрованный текст и 256-битный ключ для его расшифровки с использованием AES. Там нет соли или IV. Я использую Java. Я реализовал многие решения онлайн, но все они используют соли и входные векторы. Следующее строится нормально, но во время выполнения происходит сбой: «Соль не найдена». Какая соль?

    public class AESFileDecryption {
        public static void main(String[] args) throws Exception {

    String password = "80 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01";

    SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
    KeySpec keySpec = new PBEKeySpec(password.toCharArray());
    SecretKey tmp = factory.generateSecret(keySpec);
    SecretKey secret = new SecretKeySpec(tmp.getEncoded(), "AES");

    // file decryption
    Cipher cipher = Cipher.getInstance();
    cipher.init(Cipher.DECRYPT_MODE,secret);
    FileInputStream fis = new FileInputStream("encryptedfile.des");
    FileOutputStream fos = new FileOutputStream("plainfile_decrypted.txt");
    byte[] in = new byte[64];
    int read;
    while ((read = fis.read(in)) != -1) {
        byte[] output = cipher.update(in, 0, read);
        if (output != null)
            fos.write(output);
    }

    byte[] output = cipher.doFinal();
    if (output != null)
        fos.write(output);
    fis.close();
    fos.flush();
    fos.close();
    System.out.println("File Decrypted");
}

}


person railstg    schedule 23.06.2015    source источник
comment
StackOverflow предназначен для конкретных вопросов, связанных с программированием. У вас есть спецификация, которая, как я полагаю, является домашним заданием или заданием. Вам нужно прочитать спецификацию, провести небольшое исследование и/или обучение и начать писать решение. StackOverflow не будет писать ваш код за вас. Если вы столкнетесь с проблемами при кодировании своего решения, опубликуйте дополнительные вопросы.   -  person Dhanuka    schedule 23.06.2015
comment
Если вы сформулируете это как «Как работает расшифровка без соли или IV?» вместо мне нужен код, который делает ... тогда, вероятно, это был бы лучший вопрос.   -  person user253751    schedule 23.06.2015
comment
Для PBKDF2WithHmacSHA1 требуется соль. Я предполагаю, что Шнайер дает вам ключ напрямую, поэтому это означает, что вам не следует использовать PBKDF2WithHmacSHA1. Смотрите комментарий в моем ответе ниже для более подробной информации.   -  person TheGreatContini    schedule 23.06.2015


Ответы (3)


Вы можете расшифровать зашифрованный текст в упражнении 3.8, используя простой режим ECB AES, который не использует IV. Поскольку у вас есть ключ, в соли нет необходимости (нет вывода ключа). Используйте режим AES 256 ECB в Java и передайте ключ, как показано. Эти команды openssl в командной строке показывают, что это будет работать:

Вы должны преобразовать шестнадцатеричный код, показанный в книге, в строку байтов, например:

echo '539B333B39706D149028CFE1D9D4A407' | xxd -r -p

Вы должны использовать ключ в виде строки из 32 байтов, например, командная строка openssl преобразует шестнадцатеричный код в байтовый для вас с аргументом -K:

-K 80000000000000000000000000000000000000000000000000000000000001

И вы можете преобразовать полученный двоичный открытый текст обратно в шестнадцатеричную строку для просмотра, как в

xxd -p

Например:

echo '539B333B39706D149028CFE1D9D4A407' | xxd -r -p | openssl enc -aes-256-ecb -nopad  -d -K 8000000000000000000000000000000000000000000000000000000000000001 | xxd -p

Результат:

80706050403020100807060504030201

Если вы позволите классу Java удалить заполнение, результатом будет 15 байтов открытого текста:

807060504030201008070605040302

Этого должно быть достаточно, чтобы вы могли перейти к классам Java и воспроизвести тот же результат. Я просто хотел показать вам, что это будет работать с ECB AES 256 без каких-либо IV или соли.

person Jim Flood    schedule 23.06.2015
comment
Большое тебе спасибо. Пока я редактировал свой вопрос в ответ на предыдущую критику, вы ответили очень полезно. (Для тех, кто задается вопросом, почему ответ кажется немного не по теме, виноват я). - person railstg; 23.06.2015

IV обычно используются с такими режимами шифрования, как CBC. Я предполагаю, что Шнайер использует здесь ECB, который не включает IV. Режим ECB обычно не используется в реальном мире из-за отсутствия безопасности. Я бы посоветовал вам взглянуть на статью Википедии о режимах работы. Соли еще больше.

Если вы согласны с тем, что это проблема, с которой вы имеете дело, вы можете посмотреть здесь для кода Java для шифрования в режиме ECB.

person TheGreatContini    schedule 23.06.2015
comment
Спасибо, буду добиваться их. На самом деле я многое почерпнул из книги Шнайера. Мне просто нужно очень хорошо понимать безопасность, поэтому я копаюсь в коде как относительный новичок, и у меня возникли проблемы с этим упражнением. - person railstg; 23.06.2015
comment
Не волнуйтесь. На самом деле, хотя я и не читал книгу Шнайера, я неплохо разбираюсь в криптографии и совершенно уверен, что ваша проблема в PBKDF2WithHmacSHA1. PBKDF2 предназначен для превращения пароля в ключ, тогда как я предполагаю, что Шнайер дает вам ключ напрямую (а не пароль). См. ссылку, которую я привел (здесь выше), чтобы узнать, как правильно установить ключ. И другая вещь в ссылке использует режим ECB, а не CBC, что вам и следует делать. - person TheGreatContini; 23.06.2015

Оба ответа здесь верны об использовании ECB и, следовательно, не требуют IV (или заполнения). Вот обновленный ответ Java на вопрос 3.8:

String hexCipherText = "539b333b39706d149028cfe1d9d4a407";
String hexSecretKey =  "80000000000000000000000000000000" +
                       "00000000000000000000000000000001";

byte[] secretKey = DatatypeConverter.parseHexBinary (hexSecretKey);
byte[] cipherText = DatatypeConverter.parseHexBinary (hexCipherText);

Cipher cipher = Cipher.getInstance("AES/ECB/NoPadding");
SecretKeySpec secretKeySpec = new SecretKeySpec(secretKey,"AES");
cipher.init(Cipher.DECRYPT_MODE, secretKeySpec);

byte[] plainText = cipher.doFinal(cipherText);
String hexPlainText = DatatypeConverter.printHexBinary(plainText);

Если вы получаете сообщение об ошибке java.security.InvalidKeyException: Illegal key size or default parameters и используете Oracle JDK, вам также может потребоваться загрузить Файлы политик юрисдикции неограниченной силы расширения Java Cryptography Extension (JCE).

person mikebridge    schedule 06.12.2016