如何在 Java 中用未知的 KEY 和 IV 解密 AES?
How to decrypt AES with an unknown KEY and IV in Java?
所以我正在为我的 A 级项目创建一个游戏,我现在正处于需要能够加密和解密文本文件的阶段。
我已经找到在 GCM 模式下使用 AES-256 进行加密的方法,但是我使用的是随机生成的密钥和 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);
}
提前感谢您的任何回答,非常感谢。
不,不知道密钥就无法解密。如果任何人都可以在没有密钥的情况下解密消息,那么加密的意义何在?
如果这是为了对本地用户隐藏数据,那么最好的办法就是混淆数据。机器需要知道密钥才能对其进行加密和解密,任何有权访问该机器的人最终都可以找到该密钥并使用它为自己解密数据。即使您不向磁盘写入任何内容,本地用户也可以查看内存并找到密钥。还要记住代码可以反编译。
基本上请记住,任何拥有物理访问权限的人都是国王,您无法真正阻止他们,只是让他们慢下来。
所以你能做的最好的就是让获得钥匙的过程尽可能痛苦。类文件或 属性 文件中的字符串文字易于阅读,一点也不痛苦,因此请避免使用它们。
有关处理本地安全的相关方法,请参阅this question。
也可以考虑使用像 Proguard 这样的工具来混淆(和优化)您的代码。
您可以尝试暴力破解。
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 在计算上被认为是不可行的。唯一的 'feasible' 解密方法是使用与加密相同的密钥。 Some background on AES.
有一种更快的方法(对于 256 位在计算上仍然不可行)称为 Biclique attack.,但我认为这有点超出您的要求范围。
如果您决定需要将 AES 密钥从加密人员传递给解密人员,您可以使用 RSA encryption which uses asymetric keys. Take a look at my github for a basic RSA implementation.
所以我正在为我的 A 级项目创建一个游戏,我现在正处于需要能够加密和解密文本文件的阶段。
我已经找到在 GCM 模式下使用 AES-256 进行加密的方法,但是我使用的是随机生成的密钥和 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);
}
提前感谢您的任何回答,非常感谢。
不,不知道密钥就无法解密。如果任何人都可以在没有密钥的情况下解密消息,那么加密的意义何在?
如果这是为了对本地用户隐藏数据,那么最好的办法就是混淆数据。机器需要知道密钥才能对其进行加密和解密,任何有权访问该机器的人最终都可以找到该密钥并使用它为自己解密数据。即使您不向磁盘写入任何内容,本地用户也可以查看内存并找到密钥。还要记住代码可以反编译。
基本上请记住,任何拥有物理访问权限的人都是国王,您无法真正阻止他们,只是让他们慢下来。
所以你能做的最好的就是让获得钥匙的过程尽可能痛苦。类文件或 属性 文件中的字符串文字易于阅读,一点也不痛苦,因此请避免使用它们。
有关处理本地安全的相关方法,请参阅this question。
也可以考虑使用像 Proguard 这样的工具来混淆(和优化)您的代码。
您可以尝试暴力破解。
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 在计算上被认为是不可行的。唯一的 'feasible' 解密方法是使用与加密相同的密钥。 Some background on AES.
有一种更快的方法(对于 256 位在计算上仍然不可行)称为 Biclique attack.,但我认为这有点超出您的要求范围。
如果您决定需要将 AES 密钥从加密人员传递给解密人员,您可以使用 RSA encryption which uses asymetric keys. Take a look at my github for a basic RSA implementation.