I'm currently working on a client-server application in Java. Due to the requirements for the application I need to encrypt the traffic between client and server and decided to use a hybrid encryption approach where the server generates a public/private RSA key pair and the client generates an AES session key which will be encrypted using the RSA public key.
As I'm completely new to encryption in Java I didn't start implementing it directly into my application so I don't crash anything. I set up a test project to get a bit more familiar with how things work to get a better understanding of everything before applying it to the actual application.
I followed some tutorials where I generate a SecretKey to encrypt and decrypt the message which also works as expected. However I don't want to have one key that can be used for both, encryption and decryption, but rather have a PrivateKey and a PublicKey which I'm able to generate using KeyPairGenerator.
The problem is that when I do exactly the same things using the PrivateKey and the PublicKey I get a NullPointerException where it says "No installed provider supports this key: (null)". When trying to find some information on that problem I only found solutions that use a single SecretKey but that works for me as already mentioned.
As I haven't done anything before with encryption in Java I'm quite lost on what I need to do now or how to solve this as I find it hard to find a solution that deals with a key pair. For some more details, here is the code I used:
@SuppressWarnings("deprecation")
public class EncryptionTest {
private SecretKey secretKey;
private PrivateKey privKey;
private PublicKey pubKey;
public static void main(String[] args) {
EncryptionTest test = new EncryptionTest();
String s = "Hello";
byte[] keyBytes = new byte[32];
byte[] message = new byte[20];
s.getBytes(0, s.length(), message, 0);
message = test.encryptKeyPair(message, keyBytes);
for (int i = 0; i < message.length; i++) {
System.out.print(message[i]);
}
System.out.println("");
message = test.decryptKeyPair(message, keyBytes);
char originalChar;
for (int i = 0; i < message.length; i++) {
originalChar = (char) message[i];
System.out.print(originalChar);
}
}
public EncryptionTest() {
try {
KeyPairGenerator keyGen = KeyPairGenerator.getInstance("AES", "SUN");
SecureRandom random = SecureRandom.getInstanceStrong();
keyGen.initialize(128, random);
KeyPair pair = keyGen.generateKeyPair();
privKey = pair.getPrivate();
pubKey = pair.getPublic();
} catch (NoSuchAlgorithmException | NoSuchProviderException e) {
}
}
public byte[] encryptMessage(byte[] message, byte[] keyBytes) {
try {
Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
secretKey = new SecretKeySpec(keyBytes, "AES");
cipher.init(Cipher.ENCRYPT_MODE, secretKey);
return cipher.doFinal(message);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (NoSuchPaddingException e) {
e.printStackTrace();
} catch (InvalidKeyException e) {
e.printStackTrace();
} catch (IllegalBlockSizeException e) {
e.printStackTrace();
} catch (BadPaddingException e) {
e.printStackTrace();
}
return null;
}
public byte[] decryptMessage(byte[] message, byte[] keyBytes) {
try {
Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
cipher.init(Cipher.DECRYPT_MODE, secretKey);
return cipher.doFinal(message);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (NoSuchPaddingException e) {
e.printStackTrace();
} catch (InvalidKeyException e) {
e.printStackTrace();
} catch (IllegalBlockSizeException e) {
e.printStackTrace();
} catch (BadPaddingException e) {
e.printStackTrace();
}
return null;
}
public byte[] encryptKeyPair(byte[] message, byte[] keyBytes) {
try {
Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, privKey);
return cipher.doFinal(message);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (NoSuchPaddingException e) {
e.printStackTrace();
} catch (InvalidKeyException e) {
e.printStackTrace();
} catch (IllegalBlockSizeException e) {
e.printStackTrace();
} catch (BadPaddingException e) {
e.printStackTrace();
}
return null;
}
public byte[] decryptKeyPair(byte[] message, byte[] keyBytes) {
try {
Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
cipher.init(Cipher.DECRYPT_MODE, pubKey);
return cipher.doFinal(message);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (NoSuchPaddingException e) {
e.printStackTrace();
} catch (InvalidKeyException e) {
e.printStackTrace();
} catch (IllegalBlockSizeException e) {
e.printStackTrace();
} catch (BadPaddingException e) {
e.printStackTrace();
}
return null;
}
}
The methods encryptMessage() and decryptMessage() are the methods that work as I only use a single secretKey and the methods encryptKeyPair() and decryptKeyPair() are the methods for encrypting and decrypting using the public / private key and the don't work for me.
Any help would be really apprectiated.