Geração de chave de criptografia / descriptografia Java openssl [duplicado]

Esta pergunta já tem uma resposta aqui:

Como descriptografar o arquivo em Java criptografado com o comando openssl usando o AES? 3 respostasProblema de criptografia AES 256 1 resposta

Estou usando o Java 8 e estou tentando emular as seguintes chamadas openssl com Java.

Criptografar:

echo -n 'hello world' | openssl enc -a -aes-256-cbc -md sha256 -pass pass:97DE:4F76

U2FsdGVkX18PnO / NLSxJ1pg6OKoLyZApMz7aBRfKhJc =

Descriptografar:

echo U2FsdGVkX18PnO/NLSxJ1pg6OKoLyZApMz7aBRfKhJc= | openssl enc -d -a -aes-256-cbc -md sha256 -pass pass:97DE:4F76

Olá Mundo

Questões:

Minha implementação não funciona. Eu visitei muitas outras respostas do StackOverflow, mas não consegui descobrir a implementação correta. Alguém pode me indicar a direção certa para resolver isso?A chamada do sistema openssl no exemplo acima usa digest sha256. Se eu usasse sha1, na implementação de Java, seria apenas uma questão de mudarPBKDF2WithHmacSHA256 comPBKDF2WithHmacSHA1?

Test.java

package test;

import java.security.spec.KeySpec;

import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.PBEKeySpec;
import javax.crypto.spec.SecretKeySpec;
import javax.xml.bind.DatatypeConverter;

public class Test {

    public static final String PASSWORD = "97DE:4F76";

    public static String encryptString(String clearText, String password) {
        return "";
    }

    // echo U2FsdGVkX18PnO/NLSxJ1pg6OKoLyZApMz7aBRfKhJc= | openssl enc -d -a -aes-256-cbc -md sha256 -pass pass:97DE:4F76
    //
    // see https://stackoverflow.com/a/992413, https://stackoverflow.com/a/15595200,
    // https://stackoverflow.com/a/22445878, https://stackoverflow.com/a/11786924
    public static String decryptString(String cypherText, String password) {
        byte[] dataBase64 = DatatypeConverter.parseBase64Binary(cypherText);
        byte[] salt = {
                (byte)0x0, (byte)0x0, (byte)0x0, (byte)0x0,
                (byte)0x0, (byte)0x0, (byte)0x0, (byte)0x0
        };

        try {
            // generate the key
            SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA256"); // "PBKDF2WithHmacSHA1"
            KeySpec spec = new PBEKeySpec(password.toCharArray(), salt, 65536, 256);
            SecretKey tmp = factory.generateSecret(spec);
            SecretKey secret = new SecretKeySpec(tmp.getEncoded(), "AES");

            // decrypt the message
            Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
            byte[] iv = cipher.getParameters().getParameterSpec(IvParameterSpec.class).getIV();
            cipher.init(Cipher.DECRYPT_MODE,, secret, new IvParameterSpec(iv));

            byte[] decrypted = cipher.doFinal(dataBase64);
            String answer = new String(decrypted, "UTF-8");
            return answer;

        } catch (Exception ex) {
            ex.printStackTrace();
        }
        return "";
    }

    public static void main(String[] args) {
        System.out.println(decryptString("U2FsdGVkX18PnO/NLSxJ1pg6OKoLyZApMz7aBRfKhJc=", PASSWORD));
    }
}

esta é a saída atual da execução do código acima:

java.security.InvalidKeyException: Illegal key size     at
         javax.crypto.Cipher.checkCryptoPerm(Cipher.java:1039)  at
         javax.crypto.Cipher.init(Cipher.java:1393)     at
         javax.crypto.Cipher.init(Cipher.java:1327)     at
         test.Test.decryptString(Test.java:42)  at
         test.Test.main(Test.java:55)

Atualizar: este é o código que acabei implementando depois de usar esta resposta:https://stackoverflow.com/a/11786924 -> possui o restante das constantes e implementação de EVP_BytesToKey

public static String decryptString(String cypherText, String password) {
        try {
            // decode the base64 cypherText into salt and encryptedString
            byte[] dataBase64 = DatatypeConverter.parseBase64Binary(cypherText);
            byte[] salt = Arrays.copyOfRange(dataBase64, SALT_OFFSET, SALT_OFFSET + SALT_SIZE);
            byte[] encrypted = Arrays.copyOfRange(dataBase64, CIPHERTEXT_OFFSET, dataBase64.length);
            System.out.println("dataBase64 = " + new String(dataBase64));
            System.out.println("salt: " + new BigInteger(1, salt).toString(16));
            System.out.println("encrypted: " + new BigInteger(1, encrypted).toString(16));    

            // --- specify cipher and digest for EVP_BytesToKey method ---
            Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
            MessageDigest sha1 = MessageDigest.getInstance("SHA-256");

            // create key and IV
            final byte[][] keyAndIV = EVP_BytesToKey(
                    KEY_SIZE_BITS / Byte.SIZE,
                    cipher.getBlockSize(),
                    sha1,
                    salt,
                    password.getBytes("ASCII"),
                    ITERATIONS);
            SecretKeySpec key = new SecretKeySpec(keyAndIV[INDEX_KEY], "AES");
            IvParameterSpec iv = new IvParameterSpec(keyAndIV[INDEX_IV]);

            // initialize the Encryption Mode
            cipher.init(Cipher.DECRYPT_MODE, key, iv);

            // decrypt the message
            byte[] decrypted = cipher.doFinal(encrypted);
            String answer = new String(decrypted, "UTF-8"); // should this be "ASCII"?
            return answer;

        } catch (Exception ex) {
            ex.printStackTrace();
        }
        return "";
    }

questionAnswers(0)

yourAnswerToTheQuestion