1

so I'm creating a game for my A level project and I'm now at the stage where I need to be able to encrypt and decrypt text files.

I have figured out encryption using AES-256 in GCM mode however I am using a randomly generated key and IV in order to encrypt the data in the first place. So I was wondering, is there any way in which I can decrypt the text file without knowing the key and iv. Alternatively, from the encryption method shown below, is there anything I could change so that I will know the key and iv when decrypting the text later on.

NOTE: I'm using the libGDX library to create the game which is why I'm not using the standard method to write to the text file.

Encryption method:

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);
}

Thank you in advance for any answers, they are very much appreciated.

QuickJAB
  • 39
  • 1
  • 1
  • 6
  • 2
    No, you cannot decrypt without knowing the key. What would the point of encryption be if anyone could decrypt the message without even having the key? – xtratic Oct 12 '18 at 18:48
  • 1
    This is not possible, without knowing the key and iv. One point though, is that you will typically see the unencrypted IV included as the initial bytes of the saved data. There is no issue with saving the IV this way. https://security.stackexchange.com/questions/17044/when-using-aes-and-cbc-is-it-necessary-to-keep-the-iv-secret – Jamie Oct 12 '18 at 18:50

2 Answers2

2

No, you cannot decrypt without knowing the key. What would the point of encryption be if anyone could decrypt the message without even having the key?

If this is intended to hide data from a local user, then pretty much the best you can is obfuscate the data. The machine needs to know the key in order to encrypt and decrypt it and anyone with access to that machine can eventually find that key and use it to decrypt the data for themselves. Even if you don't write anything to disk, local users could look at memory and find the key. Also remember that code can be decompiled.

Basically just keep in mind that anyone with physical access is king and you can't really stop them, just slow them down.

So the best you can do is make it as painful as possible to get the key. String literals in classfiles or property files are easy to read and not at all painful so avoid using those.

See this question for related ways to handle local security.

Also consider using a tool like Proguard to obfuscate (and optimize) your code in general as well.

xtratic
  • 4,600
  • 2
  • 14
  • 32
  • So because this is for a game where all the data will be stored on the users machine would it be more beneficial just to straight up obfuscate the data and cut out the encryption all together. – QuickJAB Oct 12 '18 at 20:56
  • @QuickJAB You can still use encryption as your form of obfuscation but the keys must exist somewhere on the local machine so that the game can decrypt those resources for use and since the keys will exist *somewhere* on the machine a user could find them and use them to decrypt the resources for themselves. It just comes down to how hard you make it to find the keys. – xtratic Oct 15 '18 at 15:06
1

You could try a brute force attack.

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.

Per wikipedia

In reality the 256-bit AES is considered computationally infeasible. The only 'feasible' way to decrypt would be using the same key used to encrypt. Some background on AES.

There is a faster method (still computationally infeasible for 256 bit) called Biclique attack. but I think this is a bit outside the scope of what your asking.

If you decide you need to pass your AES key from the encryption person to the decrytion person you can use RSA encryption which uses asymetric keys. Take a look at my github for a basic RSA implementation.

bsheps
  • 1,438
  • 1
  • 15
  • 26
  • 1
    Your RSA implementation is insecure. It doesn't use padding of any kind. Don't recommend RSA for transport security. TLS exists for a reason. – Luke Joshua Park Oct 12 '18 at 20:51
  • 1
    @LukeJoshuaPark Thanks for the comment and please feel free to edit my answer if I'm misleading.. The RSA implementation is purely for proof of concept and I thought it might be valuable for helping understand the options. Ofcourse TLS is the accepted way to pass symmetric keys, but discussing how to implement a TLS handshake I figured is off topic for this question. – bsheps Oct 12 '18 at 21:12
  • 1
    The beauty of it is that you don't have to implement it yourself. Don't reinvent the wheel! – Luke Joshua Park Oct 12 '18 at 21:20