Как расшифровать 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);
}

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

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

xtratic 12.10.2018 20:48

Это невозможно без знания ключа и iv. Тем не менее, один момент заключается в том, что вы обычно видите незашифрованный IV, включенный в качестве начальных байтов сохраненных данных. Нет проблем с сохранением IV таким образом. security.stackexchange.com/questions/17044/…

Jamie 12.10.2018 20:50
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
1
2
6 013
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

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

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

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

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

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

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

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

QuickJAB 12.10.2018 22:56

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

xtratic 15.10.2018 17:06

Вы можете попробовать атаку методом грубой силы.

Breaking a symmetric 256-bit key by brute force requires 2128 times more computational power than a 128-bit key. Fifty supercomputers that could check a billion billion (1018) AES keys per second (if such a device could ever be made) would, in theory, require about 3×1051 years to exhaust the 256-bit key space.

По википедии

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

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

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

Ваша реализация RSA небезопасна. Он не использует никаких отступов. Не рекомендуется использовать RSA для обеспечения безопасности транспорта. TLS существует не просто так.

Luke Joshua Park 12.10.2018 22:51

@LukeJoshuaPark Спасибо за комментарий, и, пожалуйста, не стесняйтесь редактировать мой ответ, если я ввожу в заблуждение. Реализация RSA предназначена исключительно для доказательства концепции, и я подумал, что это может быть полезно для понимания вариантов. Конечно, TLS - это общепринятый способ передачи симметричных ключей, но обсуждение того, как реализовать рукопожатие TLS, как я понял, не по теме для этого вопроса.

bsheps 12.10.2018 23:12

Прелесть в том, что вам не нужно реализовывать это самостоятельно. Не изобретайте велосипед!

Luke Joshua Park 12.10.2018 23:20

Другие вопросы по теме