0

I am unfortunately not so familiar with cryptography, but I need to implement this algorithm in java8. That means, I already have some data encrypted with this approach written in C, and the key, which is 256bit, and I need to decrypt this data using some java code. Note that all that we have in Erdelsky's approach is a key, there's no 'salt' and no 'initializing vector' (at least explicit, but I may mistake).

What have I tried? Well, a bit:

  • I tried BouncyCastle, but it fails to decrypt my data (it uses 'iv', I set it all zero, so it might be a problem)
  • I am using java 1.8.112 I got an 'Illegal key size or default parameters' exception and I tried to Hack my JDK to let it work with 256bit keys, (it uses 'iv' as well) but it fails to decrypt my data as well. The code is the following:

    public static void DecryptData(byte[] Contents, int NumBytes, byte[] KeyBytes, int KeyOffset, int NumKeyBytes)
    {
        final int AESBlockSize = 16;
        final byte[] EncryptionDecryptionBuffer = new byte[AESBlockSize];
        final byte[] InitializingVector = {
            0, 0, 0, 0,
            0, 0, 0, 0,
            0, 0, 0, 0,
            0, 0, 0, 0
        };
        try
        {
            final Cipher AES256Cipher = Cipher.getInstance("AES/CBC/NoPadding");
            final SecretKeySpec secretKeySpec = new SecretKeySpec(KeyBytes, KeyOffset, NumKeyBytes, "AES");
    
            AES256Cipher.init(Cipher.DECRYPT_MODE, secretKeySpec, new IvParameterSpec(InitializingVector));
    
            // Decrypt the data a block at a time
            for (int Offset = 0; Offset < NumBytes; Offset += AESBlockSize)
            {
                // Update and copy to the EncryptionDecryptionBuffer
                AES256Cipher.update(Contents, Offset, AESBlockSize, EncryptionDecryptionBuffer);
    
                // Copy to the initial array
                System.arraycopy(EncryptionDecryptionBuffer, 0, Contents, Offset, AESBlockSize);
            }
        }
        catch (GeneralSecurityException e)
        {
            throw new RuntimeException(e);
        }
    }
    

I am still looking for the solution, please help. Thanks.

Maksym Labutin
  • 561
  • 1
  • 8
  • 17
Netherwire
  • 2,669
  • 3
  • 31
  • 54
  • You specify CBC mode in your code, that requires an IV. Use ECB mode if you don't have an IV. Notice that ECB mode is insecure .. – Ebbe M. Pedersen Dec 20 '18 at 14:30
  • The way they handle the key / password in the rijndael.txt file is suspect. They pickup a binary key directly from argv[1] .. – Ebbe M. Pedersen Dec 20 '18 at 14:40
  • @EbbeM.Pedersen Thanks, I'll try it asap, maybe it is insecure but it is a part of one game engine and I can not change it :) – Netherwire Dec 20 '18 at 14:42
  • 1
    You don't need to hack your jdk; the most recent JDK will not give you that exception, and you don't indicate that you get that exception. You said "it fails" but then you didn't give any additional information on what error message or other indicator you received that it failed. – President James K. Polk Dec 20 '18 at 15:06
  • The library you linkek has EBC,CBC and CFB mode support. it uses RFC 2040-like padding scheme which is equal to PKCS#5 padding scheme. And as noted by James, what are the errors and what is the code from C side? – kelalaka Dec 20 '18 at 15:15
  • @JamesKPolk by 'it fails' i mean 'my decrypted data is not the same as the initial plain text', I did not mentioned any exceptions and thus I thought that was obvious – Netherwire Dec 20 '18 at 15:31
  • @kelalaka As EbbeM.Pedersen noticed, there is an example http://www.efgh.com/software/rijndael.txt I did not used any other C code except it – Netherwire Dec 20 '18 at 15:34
  • That's just a low level implementation of AES. You haven't specified how you've used it, and you haven't shown any input / output for both the C or Java implementation. The latest JDK's have no restrictions on the AES key size; you should use supported versions of Java to generate security related code (or any code, really). – Maarten Bodewes Dec 20 '18 at 17:03
  • 1
    @MaartenBodewes I showed both reference implementation and my code. The question was 'How can I achieve the same behavior in java?', there are many top-rated 'is there an equivalent of x for y?' questions here, what's a problem? Did you read my question? I am using JDK 1.8.112, and I don't care about 'secure code' within this task, I just have to decrypt data that was previously encrypted with Erdelsky's implementation, which was mentioned in the first sentence. Nevertheless, this did not prevent EbbeM.Pedersen from giving a correct answer, which I will add if he doesn’t do this himself. – Netherwire Dec 20 '18 at 17:42
  • 1
    Those questions are kind of a problem themselves as they are just about porting data for a specific user, in this case you. Sometimes it can be useful, but only if we know how the library is used. Your question does not make that clear, did you use the scheme for the command line interface for instance? How did you pad your data? The code you linked to doesn't provide a standard padding method. Is it too much to ask to at least show your code, input and output? – Maarten Bodewes Dec 20 '18 at 17:55
  • For instance, we could indicate that you would need to pad / unpad with space characters if you'd use the command line. – Maarten Bodewes Dec 20 '18 at 18:12

1 Answers1

0

Some extra background. I tried to create a java implementation of a packing algorithm for some game engine. I suppose that ECB encryption was selected to reduce entropy between different versions of packed assets (because patching system is trying to install chunks of already encrypted content into existing data). What about JDK 1.8.112 - I used Excelsior Jet to AOT-compile my program (it will be open-source, I'll append the link to this post a bit later), but unfortunately, my previous version of the AOT compiler only supported 1.8.112, so I used same JDK version to ensure compatibility.

Verbose answer for non-crypto-guys (like me) in facts:

  1. The block size is always 16 bytes-wide, this was completely okay.
  2. The key length is 256 bit-wide (or 32 bytes), you could not use that long keys in older JDK patches, but then later, the restriction has been removed, so update your JDK to Java 9, Java 8u161, Java 7u171 or 6u181, or download and install this Unlimited Strength Jurisdiction Policy.
  3. You have to use ECB encryption to match Erdelsky's Rijndael, this is less secure than CBC, but it can still be used for compatibility reasons.

Thanks everyone for the answer and a discussion. Cheers!

Netherwire
  • 2,669
  • 3
  • 31
  • 54