Hello dear people of stackoverflow,
I'm currently developing/implementing security measures within my application and somewhat experiencing issues with encryption and decryption of certain data.
Yesterday in fact i was able to encrypt a message and then decrypt the encrypted message with the very same instance of the class - yet could not do vice versa. That's what I wanted to post today (about the issue) -
After pushing the latest changes from the linux system I've worked and trying to continue working on the windows pc, the following error was thrown:
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)
So I tried finding a solution but did not find any, so here's what I tried so far:
Updating to JDK 9/10/11 is not an option for me, I tried it, I failed miserably and there'd be too much to adapt if I'd to the move up (it's not worth the effort as of this moment)
I've read something about Java Cryptography Extension (JCE), yet that does not apply to me since I am running the JDK version 1.8.66 (and since 1.8.55 it no longer requires any kind of file installed within the java directory)
Invalidated cache (IntelliJ) + Restarted my PC
Resetted the project state to the initial commit (git hard reset)
My class:
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;
}
}
My test class:
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);
}
}
Please don't mind any conventional mistake/bad practice, I'm a newcomer when it comes to cryptography (reading my way into it as of this moment)
Any help or input would be appreciated!
Edit:
Thank you for your immediate replies!
Unfortunately I'm having another error thrown. Full output:
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)
changed code:
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 "";
}