Здравствуйте, дорогие люди из stackoverflow,
В настоящее время я разрабатываю / внедряю меры безопасности в своем приложении и испытываю некоторые проблемы с шифрованием и дешифрованием определенных данных.
Вчера фактически я смог зашифровать сообщение, а затем расшифровать зашифрованное сообщение тем же экземпляром класса - но не смог сделать наоборот. Это то, что я хотел опубликовать сегодня (о проблеме) -
После отправки последних изменений из системы Linux, с которой я работал, и попытки продолжить работу на компьютере с Windows, была выдана следующая ошибка:
java.security.InvalidKeyException: Illegal key size or default parameters
at javax.crypto.Cipher.checkCryptoPerm(Cipher.java:1026)
at javax.crypto.Cipher.implInit(Cipher.java:801)
at javax.crypto.Cipher.chooseProvider(Cipher.java:864)
at javax.crypto.Cipher.init(Cipher.java:1249)
at javax.crypto.Cipher.init(Cipher.java:1186)
at com.x.backend.security.Decrypter.encrypt(Decrypter.java:43)
at crypto.CryptoTest.main(CryptoTest.java:11)
java.lang.NullPointerException
at javax.crypto.spec.IvParameterSpec.<init>(IvParameterSpec.java:53)
at com.x.backend.security.Decrypter.decrypt(Decrypter.java:54)
at crypto.CryptoTest.main(CryptoTest.java:12)
Итак, я попытался найти решение, но не нашел, поэтому вот что я попробовал:
Обновление до JDK 9/10/11 для меня не вариант, я попробовал это, я потерпел неудачу, и было бы слишком много, чтобы приспособиться, если бы я поднялся (это не стоит усилия на данный момент)
Я читал кое-что о Java Cryptography Extension (JCE), но это не относится ко мне, так как я использую версию JDK 1.8.66 (а с 1.8.55 его нет больше требуется любой тип файла, установленного в каталоге java)
Недействительный кеш (IntelliJ) + Перезагрузка моего компьютера
Сброс состояния проекта до первоначального коммита (git hard reset)
Мой класс:
public class Decrypter {
private static Decrypter instance;
private Cipher cipher;
private byte[] IV;
private SecretKeySpec secretKeySpec;
private Decrypter() {
initialize();
}
private void initialize() {
try {
final byte[] salt = "@1jq3#-o1_uHvaL:".getBytes();
final String key = "hehexd";
final int iterationCount = 12;
final int keyStrength = 256;
this.cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
this.secretKeySpec = new SecretKeySpec(SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1").generateSecret(new PBEKeySpec(key.toCharArray(), salt, iterationCount, keyStrength)).getEncoded(), "AES");
} catch (InvalidKeySpecException | NoSuchAlgorithmException | NoSuchPaddingException e) {
e.printStackTrace();
}
}
public final String encrypt(String data) {
try {
cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec);
IV = cipher.getParameters().getParameterSpec(IvParameterSpec.class).getIV();
return Base64.getEncoder().encodeToString(cipher.doFinal(data.getBytes()));
} catch (Exception e) {
e.printStackTrace();
}
return "";
}
public final String decrypt(String base64EncryptedData) {
try {
cipher.init(Cipher.DECRYPT_MODE, secretKeySpec, new IvParameterSpec(IV));
byte[] decryptedData = Base64.getDecoder().decode(base64EncryptedData);
byte[] utf8 = cipher.doFinal(decryptedData);
return new String(utf8, StandardCharsets.UTF_8);
} catch (Exception e) {
e.printStackTrace();
}
return "";
}
public static Decrypter getInstance() {
return instance == null ? instance = new Decrypter() : instance;
}
}
Мой тестовый класс:
public class CryptoTest {
public static void main(String[] args) {
String encrypted = Decrypter.getInstance().encrypt("lol");
String decrypted = Decrypter.getInstance().decrypt(encrypted);
System.out.println("Verification: PLAINTEXT -> ENCRYPT: " + encrypted);
System.out.println("Verification: ENCRYPT -> DECRYPT: " + decrypted);
}
}
Пожалуйста, не возражайте против любой обычной ошибки / плохой практики, я новичок, когда дело доходит до криптографии (читая мой путь к этому с этого момента)
Любая помощь или вклад будут оценены!
Edit:
Спасибо за ваши немедленные ответы!
К сожалению, у меня появляется другая ошибка.
Полный вывод:
Verification: PLAINTEXT -> ENCRYPT:
java.security.InvalidKeyException: Illegal key size
Verification: PLAINTEXT -> DECRYPT:
at javax.crypto.Cipher.checkCryptoPerm(Cipher.java:1039)
at javax.crypto.Cipher.implInit(Cipher.java:805)
at javax.crypto.Cipher.chooseProvider(Cipher.java:864)
at javax.crypto.Cipher.init(Cipher.java:1396)
at javax.crypto.Cipher.init(Cipher.java:1327)
at com.x.backend.security.Decrypter.encrypt(Decrypter.java:48)
at crypto.CryptoTest.main(CryptoTest.java:11)
java.security.InvalidKeyException: No installed provider supports this key: javax.crypto.spec.SecretKeySpec
at javax.crypto.Cipher.chooseProvider(Cipher.java:893)
at javax.crypto.Cipher.init(Cipher.java:1396)
at javax.crypto.Cipher.init(Cipher.java:1327)
at com.x.backend.security.Decrypter.decrypt(Decrypter.java:58)
at crypto.CryptoTest.main(CryptoTest.java:12)
измененный код:
public final String encrypt(String data) {
try {
IV = new IvParameterSpec("testtesttesttest".getBytes());
cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec, IV);
return Base64.getEncoder().encodeToString(cipher.doFinal(data.getBytes()));
} catch (Exception e) {
e.printStackTrace();
}
return "";
}