whyn
whyn

Reputation:

Java decryption of an encrypted file with openssl aes 256 cbc

I have been trying for several days to decrypt in java a message encrypted with openssl. The message was encrypted with the following command:

openssl enc -e -aes-256-cbc -kfile $ file.key -in toto -out toto.enc.

The file file.key contains the symmetric key of 256 bits. No salt has been specified in the command and yet the file begins with Salted__. Here is the class that I coded to try to decrypt the file but impossible to get anything even by removing the 16 characters of the file namely the: Salted__ + the salt encrypted. I understood that openssl did it by default. When I try to decipher, an exception is thrown in relation to the encrypted text.

Could someone help me? a track ? an idea ?

Thank you very much.

The code :

  public class Java {

       private static SecretKey key = null;         
       private static Cipher cipher = null;

       public static void main(String[] args) throws Exception
       {
          String filename = RESOURCES_DIR + "toto.enc";

          byte[] key = Base64.decode("2AxIw+/AzDBj83OILV9GDpOs+izDFJEhD6pve/IPsN9=");
          SecretKeySpec secretKey = new SecretKeySpec(key, "AES");
          cipher = Cipher.getInstance("AES");

          cipher.init(Cipher.DECRYPT_MODE, secretKey);
          byte[] test = Base64.decode(readFile(filename));
          byte[] decryptedBytes = cipher.doFinal(test);
          String decryptedText = new String(decryptedBytes, "UTF8");

          System.out.println("After decryption: " + decryptedText);
       }

        public final static String RESOURCES_DIR = "C:/Users/toto/Desktop/";

        static String readFile(String filename) throws FileNotFoundException, IOException {
            FileReader fr;
            BufferedReader br;

            fr = new FileReader(new File(filename));
            br = new BufferedReader(fr);
            String str;
            String res = "";
            while ((str = br.readLine()) != null) {
                res += str;
            }
            return res;
        }
    }

The error :

Exception in thread "main" javax.crypto.BadPaddingException: Given final block not properly padded
    at com.sun.crypto.provider.CipherCore.doFinal(CipherCore.java:811)
    at com.sun.crypto.provider.CipherCore.doFinal(CipherCore.java:676)
    at com.sun.crypto.provider.AESCipher.engineDoFinal(AESCipher.java:313)
    at javax.crypto.Cipher.doFinal(Cipher.java:2131)
    at deciphertodeploytest6.Java.main(Java.java:52)

Upvotes: 0

Views: 2606

Answers (1)

dave_thompson_085
dave_thompson_085

Reputation: 39020

No, file.key does not contain the key. openssl enc -kfile reads a password which is NOT the key but is used to derive the key and also IV (when applicable, and it is here); see the man page. This key derivation uses random salt by default, and since 2016-08 the default hash depends on OpenSSL version which you didn't state. Also, Cipher.getInstance("AES") in Java defaults to ECB not CBC as you need. (It also defaults to 'PKCS5' padding, which does match OpenSSL, even though technically it should be called PKCS7 not PKCS5.)

To match in Java the PBKDF (and thus key and IV) used by openssl enc you can either use BouncyCastle or code the equivalent of OpenSSL's EVP_BytesToKey; see dupe or near-dupe Qs:
Java equivalent of an OpenSSL AES CBC encryption
How to decode a string encoded with openssl aes-128-cbc using java?
How to decrypt AES encrypted file with '-nosalt' param
How to decrypt file in Java encrypted with openssl command using AES?
and my attempt at canonical https://crypto.stackexchange.com/questions/3298/is-there-a-standard-for-openssl-interoperable-aes-encryption/#35614

Upvotes: 1

Related Questions