Как расшифровать AES с неизвестным ключом и 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);
}
Заранее благодарю за любые ответы, они очень ценятся.
2 ответа
Нет, вы не можете расшифровать, не зная ключа. Какой будет смысл шифрования, если кто-нибудь сможет расшифровать сообщение, даже не имея ключа?
Если это предназначено для сокрытия данных от локального пользователя, то самое лучшее, что вы можете, - это запутать данные. Машина должна знать ключ для того, чтобы зашифровать и расшифровать его, и любой, у кого есть доступ к этой машине, может в конечном итоге найти этот ключ и использовать его для дешифрования данных для себя. Даже если вы ничего не записываете на диск, локальные пользователи могут посмотреть на память и найти ключ. Также помните, что код можно декомпилировать.
По сути, просто имейте в виду, что любой, кто имеет физический доступ, является королем, и вы не можете остановить их, просто замедлите их.
Поэтому лучшее, что вы можете сделать, - это сделать так, чтобы ключ был как можно более болезненным. Строковые литералы в файлах классов или файлов свойств легко читаются и совсем не болезненны, поэтому избегайте их использования.
Посмотрите этот вопрос, чтобы узнать о способах обеспечения локальной безопасности.
Также рассмотрите возможность использования такого инструмента, как Proguard, чтобы запутать (и оптимизировать) ваш код в целом.
Вы можете попробовать атаку грубой силой.
Для взлома симметричного 256-битного ключа грубой силой требуется в 2128 раз больше вычислительной мощности, чем для 128-битного ключа. Пятьдесят суперкомпьютеров, которые могли бы проверять миллиард миллиардов (1018) ключей AES в секунду (если бы такое устройство могло когда-либо создаваться), теоретически потребовали бы около 3×1051 года, чтобы исчерпать 256-битное пространство ключей.
На самом деле 256-битный AES считается вычислительно неосуществимым. Единственный "выполнимый" способ расшифровки - использовать тот же ключ, что и для шифрования. Некоторый фон на AES.
Существует более быстрый метод (все еще невозможный в вычислительном отношении для 256 бит), называемый Biclique attack. но я думаю, что это немного выходит за рамки того, что вы просите.
Если вы решите, что вам необходимо передать свой ключ AES от лица, занимающегося шифрованием, лицу, осуществляющему расшифровку, вы можете использовать шифрование RSA, которое использует асимметричные ключи. Взгляните на мой github для базовой реализации RSA.