Генерация ключей шифрования / дешифрования Java openssl

Я использую 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

Привет мир

Вопросов:

  1. Моя реализация не работает. Я посетил многие другие ответы StackOverflow, но не смог понять правильную реализацию. Может ли кто-нибудь указать мне в правильном направлении для решения этого?
  2. Системный вызов 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 ""; } 

Interesting Posts

Является ли auto в качестве параметра в регулярной функции расширением GCC 4.9?

Как я могу найти историю bash и повторить команду?

Приращение iteratorов: ++ это более эффективно, чем это ++?

Как я могу сделать ссылку на клики в NSAttributedString?

ошибка keytool Keystore была изменена или пароль был неверен

@RunWith (MockitoJUnitRunner.class) против MockitoAnnotations.initMocks (это)

. Net эквивалент старой функции vb left (string, length)?

Пакетный файл для удаления файлов старше N часов или минут

Возможно ли одноуровневое многоязычное развертывание Windows Forms (ILMerge и спутниковые сборки / локализация)?

Несколько форм на одной странице с использованием колбы и WTForms

Рекурсивные подстановочные знаки в GNU?

В чем разница между перегрузкой и переопределением метода?

Почему имя аргумента shorthand $ 0 возвращает кортеж всех параметров?

Работает ли UIGestureRecognizer на UIWebView?

case switch: ошибка: метка case не сводится к целочисленной константе

Давайте будем гением компьютера.