-1

I am provided two files encrypted_key.enc and encrypted_data.csv.enc. I need to use my private key to decrypt the encrypted_key.enc to get a symmetric key and then use that symmetric key to decrypt the encrypted_data.csv.enc file.

On the terminal, the following commands get the job done:

openssl rsautl -decrypt -ssl -inkey my_private_key -in encrypted_key.enc -out key

openssl aes-256-cbc -d -in encrypted_data.csv.enc -out secret.txt -pass file:key

My goal is to perform the java equivalent of the two commands. I was able to successfully decrypt the first file and retrieve the symmetric key.

Now I'm unable to use that symmetric key to decrypt the csv file. My issue arises in the decipher.init(Cipher.DECRYPT_MODE, keySpec); I receive the following stacktrace

Exception in thread "main" java.security.InvalidKeyException: Illegal key size or default parameters

I'm unclear on what exactly I'm missing from the decryption process. I've tried changing the cipher provider but that didn't help. Other posts have posted solutions using an IVParameterSpec but my decryption case doesn't seem to need it or I'm confused on where to put it.

    File file = new File("my_private_key");
    PrivateKey pk = getPrivateKey(file);

    // Decrypt secret key
    Cipher cipher = Cipher.getInstance("RSA");
    cipher.init(Cipher.DECRYPT_MODE, pk);
    File skFile = new File("encrypted_key.enc");
    FileInputStream fileInputStream = new FileInputStream(skFile);
    byte[] decodedBytes = IOUtils.toByteArray(fileInputStream);
    byte[] original = cipher.doFinal(decodedBytes);
    String decodedOriginal = new String(Base64.encodeBase64(original));
    System.out.println(decodedOriginal);

    // Use the secret key for decrypting file
    File csvFile =
            new File(
                    "encrypted_data.csv.enc");
    FileInputStream csvIS = new FileInputStream(csvFile);
    Cipher decipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
    SecretKeySpec keySpec = new SecretKeySpec(original, "AES");

    decipher.init(Cipher.DECRYPT_MODE, keySpec);

    byte[] csvOriginal = decipher.doFinal(IOUtils.toByteArray(csvIS));
    String csvContents = new String(csvOriginal);
    System.out.println(csvContents);

1 Answer 1

1

Before Java 1.8 (I think, somewhere around there) you are limited by the Java Unlimited Strength Policy for key sizes above 128-bits. This is the most likely cause of the exception you are getting.

Unfortunately this won't fix your code. openssl with the pass flag uses an insecure KDF named EVP_BytesToKey(). Java doesn't natively support this KDF. You don't want to use it anyway since it is insecure. Update the upstream code to use a better KDF like PBKDF2. There is native support for this in Java.

Further, you're using CBC mode in openssl and ECB mode in Java. And you aren't specifying an IV in openssl. I get the impression you didn't write the Java code yourself. You might benefit from taking the time to learn and research what is actually happening in your code and in the commands you are executing and you might be better equipped to solve the problem.

Sign up to request clarification or add additional context in comments.

4 Comments

Oracle/Sun Java (but not OpenJDK) below 8u161 or 9 have the limited-to-128bits issue, although 8u151/2 have a partial solution (text edit java.security instead of download jars). openssl enc in PBE mode uses EVP_BytesToKey to derive BOTH key and IV if needed (which it is for CBC). If you transport a good-random key (not password) with RSA, you don't need any PBKDF (and if the correct size not even a KBKDF).
@dave_thompson_085 Thanks for clearing up. And I agree, transporting the key directly is probably preferred. You can specify a key in hex using the -K flag to openssl enc I believe.
@LukeJoshuaPark You're right in that I pieced together this Java code from whatever help I got from StackOverflow and other sources. Regarding the openssl code snippet, what would be the more secure bash command to decrypt the file? Also, even in CBC mode in Java, I'm required to specify the IV in openssl, but I'm unclear on where I would derive the value.
@user2548635 The issue isn't regarding a secure way to decrypt the file, it is regarding a secure way to encrypt the file in the first place. The issue really comes down to the KDF that OpenSSL uses: it is simply just bad. You should adjust how the file is encrypted originally so that it can be decrypted using openssl enc with the -K and -iv flags.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.