Как расшифровать AES с неизвестным KEY и IV в Java?

поэтому я создаю игру для своего проекта уровня A, и сейчас я нахожусь на этапе, когда мне нужно иметь возможность шифровать и расшифровывать текстовые файлы.

Я выяснил шифрование с использованием AES-256 в режиме GCM, однако я использую случайно сгенерированный ключ и IV, чтобы в первую очередь зашифровать данные. Поэтому мне было интересно, есть ли способ расшифровать текстовый файл, не зная ключа и iv. В качестве альтернативы, из метода шифрования, показанного ниже, есть ли что-нибудь, что я мог бы изменить, чтобы я знал ключ и iv при расшифровке текста позже.

ПРИМЕЧАНИЕ. Я использую библиотеку libGDX для создания игры, поэтому я не использую стандартный метод записи в текстовый файл.

Метод шифрования:

public void encrypt ()
{
    byte[] input = w.getSprites().toString().getBytes(); // Data to be encrypted
    byte[] encrypted = null; // Encrypted output
    Cipher cipher; // Cipher algorithm to be used

    try {

        // Setup the cipher algorithm to use and select the wanted mode
        // AES is the cipher algorithm GCM is the mode
        cipher = Cipher.getInstance("AES/GCM/NoPadding");

        // Generate a random key for the encryption
        KeyGenerator keyGenerator = KeyGenerator.getInstance("AES");
        keyGenerator.init(256);
        SecretKey key = keyGenerator.generateKey();

        // Generate a random iv for the encryption
        SecureRandom randomSecureRandom = new SecureRandom();
        byte[] iv = new byte[cipher.getBlockSize()];
        randomSecureRandom.nextBytes(iv);

        // Encrypt the data
        cipher.init(Cipher.ENCRYPT_MODE, key, randomSecureRandom);
        encrypted = new byte[cipher.getOutputSize(input.length)];
        int enc_len = cipher.update(input, 0, input.length, encrypted, 0);
        enc_len += cipher.doFinal(encrypted, enc_len);
    }
    catch (NoSuchAlgorithmException | 
           NoSuchPaddingException | 
           InvalidKeyException | 
           ShortBufferException | 
           IllegalBlockSizeException | 
           BadPaddingException e) { e.printStackTrace(); }

    FileHandle f = Gdx.files.local("bin/default/saves/default/test.txt");
    f.writeString(encrypted.toString(), false);
}

Заранее спасибо за любые ответы, они очень ценятся.


person QuickJAB    schedule 12.10.2018    source источник
comment
Нет, вы не можете расшифровать, не зная ключа. В чем был бы смысл шифрования, если бы любой мог расшифровать сообщение, даже не имея ключа?   -  person xtratic    schedule 12.10.2018
comment
Это невозможно без знания ключа и iv. Однако один момент заключается в том, что вы обычно видите незашифрованный IV, включенный в качестве начальных байтов сохраненных данных. Нет проблем с сохранением IV таким образом. security.stackexchange.com/questions/17044/   -  person Jamie    schedule 12.10.2018


Ответы (2)


Нет, вы не можете расшифровать, не зная ключа. В чем был бы смысл шифрования, если бы любой мог расшифровать сообщение, даже не имея ключа?

Если это предназначено для сокрытия данных от локального пользователя, то лучшее, что вы можете сделать, — это запутать данные. Машина должна знать ключ, чтобы зашифровать и расшифровать его, и любой, у кого есть доступ к этой машине, может в конечном итоге найти этот ключ и использовать его для расшифровки данных для себя. Даже если вы ничего не записываете на диск, локальные пользователи могут заглянуть в память и найти ключ. Также помните, что код можно декомпилировать.

По сути, просто имейте в виду, что любой, у кого есть физический доступ, является королем, и вы не можете остановить его, просто замедлите.

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

См. этот вопрос для связанных способов обеспечения локальной безопасности.

Также рассмотрите возможность использования такого инструмента, как Proguard, для запутывания (и оптимизации) вашего кода в целом, как хорошо.

person xtratic    schedule 12.10.2018
comment
Так как это для игры, где все данные будут храниться на компьютере пользователя, было бы более выгодно просто запутать данные и полностью отключить шифрование. - person QuickJAB; 12.10.2018
comment
@QuickJAB Вы по-прежнему можете использовать шифрование в качестве формы запутывания, но ключи должны существовать где-то на локальном компьютере, чтобы игра могла расшифровать эти ресурсы для использования, а поскольку ключи будут существовать где-то на компьютере, пользователь мог найти их и использовать для расшифровки ресурсов для себя. Все сводится к тому, насколько сложно вам найти ключи. - person xtratic; 15.10.2018

Можно попробовать атаку грубой силы.

Взлом симметричного 256-битного ключа методом грубой силы требует в 2128 раз большей вычислительной мощности, чем 128-битный ключ. Пятьдесят суперкомпьютеров, которые могли бы проверять миллиард миллиардов (1018) ключей AES в секунду (если такое устройство когда-либо будет создано), теоретически потребовали бы около 3×1051 лет, чтобы исчерпать пространство 256-битных ключей.

Согласно википедии

В действительности 256-битный AES считается вычислительно неосуществимым. Единственный «осуществимый» способ расшифровки — использование того же ключа, который использовался для шифрования. Некоторые сведения об AES.

Существует более быстрый метод (все еще невыполнимый с вычислительной точки зрения для 256-битной версии), который называется атака Biclique. но я думаю это немного выходит за рамки того, о чем вы спрашиваете.

Если вы решите, что вам нужно передать ключ AES от лица, выполняющего шифрование, лицу, занимающемуся расшифровкой, вы можете использовать Шифрование RSA, использующее асимметричные ключи. Взгляните на мой github для базовой реализации RSA.

person bsheps    schedule 12.10.2018
comment
Ваша реализация RSA небезопасна. Он не использует отступы любого рода. Не рекомендуется использовать RSA для обеспечения безопасности транспорта. TLS существует не просто так. - person Luke Joshua Park; 12.10.2018
comment
@LukeJoshuaPark Спасибо за комментарий и, пожалуйста, не стесняйтесь редактировать мой ответ, если я ввожу в заблуждение. Реализация RSA предназначена исключительно для проверки концепции, и я подумал, что это может быть полезно для понимания вариантов. Конечно, TLS является общепринятым способом передачи симметричных ключей, но обсуждение того, как реализовать рукопожатие TLS, я решил, что это не тема для этого вопроса. - person bsheps; 13.10.2018
comment
Прелесть его в том, что вам не нужно реализовывать его самостоятельно. Не изобретайте велосипед! - person Luke Joshua Park; 13.10.2018