Генерация ключа шифрования / дешифрования Java openssl [дубликат]

На этот вопрос уже есть ответ здесь:

Как расшифровать файл в Java, зашифрованный командой openssl с помощью AES? 3 ответаПроблема шифрования AES 256 1 ответ

Я использую Java 8 и пытаюсь эмулировать следующие вызовы openssl с Java.

Шифрование:

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

U2FsdGVkX18PnO / NLSxJ1pg6OKoLyZApMz7aBRfKhJc =

Расшифровать:

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

Привет, мир

Вопросы:

Моя реализация не работает. Я посетил много других ответов StackOverflow, но не смог понять правильную реализацию. Кто-нибудь может указать мне правильное направление для решения этой проблемы?Системный вызов openssl в приведенном выше примере использует дайджест sha256. Если бы я использовал sha1 вместо реализации Java, это было бы просто вопросом измененияPBKDF2WithHmacSHA256 сPBKDF2WithHmacSHA1?

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

это текущий результат выполнения кода выше:

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)

Обновить: это код, который я реализовал после того, как использовал этот ответ:https://stackoverflow.com/a/11786924 -> имеет остальные константы и реализацию 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 "";
    }

Ответы на вопрос(0)

Ваш ответ на вопрос