Генерация ключей шифрования / дешифрования Java openssl
Я использую Java 8, и я пытаюсь подражать следующим вызовам openssl с Java.
Шифрование:
echo -n 'hello world' | openssl enc -a -aes-256-cbc -md sha256 -pass pass:97DE:4F76
- C # Экспорт частного / открытого ключа RSA из RSACryptoServiceProvider в строку PEM
- Шифрование / Расшифровка больших файлов (.NET)
- Фундаментальное различие между алгоритмами Hashing и Encryption
- Зачем использовать class C # System.Random вообще, а не System.Security.Cryptography.RandomNumberGenerator?
- Шифровать и расшифровать строку в C #?
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 ""; }
- Шифрование файлов cookie в ASP.NET
- Проблема шифрования RSA
- Использование AES-шифрования в C #
- Лучший способ создать ключи AES, чем посев SecureRandom
- Android 4.2 нарушил мой шифрованный / дешифрованный код, и предоставленные решения не работают
- Что делает оператор?
- Шифровать пароль в файлах конфигурации?
- Размер подписи RSA?