So i am building a java app which uses a secure RSA connection to deliver data (at the moment i am coding encryption/decryption techniques by hand if there is a library or a better way to do this feel free to write it), it's the first time i am doing this so i don't know that much of the topic.
This is the class i use both on the server and the client side to encrypt/decrypt:
public class RSAEncryption extends AsymmetricalEncryption {
public RSAEncryption() {
super("RSA");
}
@Override
public byte[] encrypt(String data) {
Cipher cipher = null;
byte[] encryptedData = new byte[0];
try {
cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.ENCRYPT_MODE, super.sharedKey);
encryptedData = cipher.doFinal(data.getBytes());
encryptedData = Base64.getEncoder().encode(encryptedData);
} catch (Exception e) {
System.err.println("Error on Cipher initialization " + e);
}
return encryptedData;
}
@Override
public byte[] decrypt(byte[] data) {
Cipher cipher = null;
byte[] encryptedData = null;
try {
cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.DECRYPT_MODE, super.privateKey);
encryptedData = cipher.doFinal(Base64.getDecoder().decode(data));
} catch (Exception e) {
e.printStackTrace();
}
return encryptedData;
}
}
The RSAEncryption class AsymmetricalEncryption because i would like in the future to implement different encryption protocols. This is the Server-side connection:
public class Connection extends Thread {
private Socket connection;
private ObjectInputStream ois;
private ObjectOutputStream oos;
private AsymmetricalEncryption encryption;
public Connection(Socket connection) {
try {
this.connection = connection;
this.ois = new ObjectInputStream(connection.getInputStream());
this.oos = new ObjectOutputStream(connection.getOutputStream());
encryption = new RSAEncryption();
// sending the public key
oos.writeUTF(encryption.encodeBase64PublicKey(encryption.publicKey));
oos.flush();
// read sharedKey
String encodedKey = ois.readUTF();
encryption.setSharedKey(encryption.decodeBase64PublicKey(encodedKey, "RSA"));
this.start();
} catch (Exception e) {
e.printStackTrace();
}
}
public Connection(Socket connection, String encryptionMethod) {
try {
//this.connection = connection;
this.ois = new ObjectInputStream(connection.getInputStream());
this.oos = new ObjectOutputStream(connection.getOutputStream());
encryption = AsymmetricalEncryptionFactory.getAsymmetricalEncryption(encryptionMethod);
// sending the public key
oos.writeUTF(encryption.encodeBase64PublicKey(encryption.publicKey));
oos.flush();
// read sharedKey
String encodedKey = ois.readUTF();
encryption.setSharedKey(encryption.decodeBase64PublicKey(encodedKey, encryptionMethod));
this.start();
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public void run() {
boolean isRunning = true;
while(isRunning){
try {
byte[] encryptedStringRequest = ois.readAllBytes();
System.out.println("Encrypted Request: " + encryptedStringRequest);
byte[] stringRequest = encryption.decrypt(encryptedStringRequest);
System.out.println("Request: " + new String(stringRequest));
System.out.println("When you fix the bug remeber to decomment the following two lines of Connection");
//Request request = Request.parse(this, new JSONObject(stringRequest));
//RequestQueue.RequestQueue().enqueue(request);
} catch (Exception e) {
e.printStackTrace();
isRunning = false;
}
}
}
public void response(Response response){
try {
byte[] encryptedStringResponse = encryption.encrypt(response.toJSONString().getBytes());
oos.write(encryptedStringResponse);
oos.flush();
} catch (IOException e) {
System.err.println("Error during response sending "+ e);
}
}
}
This is the Client-side Connection:
public class Connection {
private Socket connection;
private ObjectInputStream ois;
private ObjectOutputStream oos;
private AsymmetricalEncryption encryption;
public Connection(Socket connection) {
try {
this.connection = connection;
this.oos = new ObjectOutputStream(connection.getOutputStream());
this.ois = new ObjectInputStream(connection.getInputStream());
encryption = new RSAEncryption();
// sending the public key
oos.writeUTF(encryption.encodeBase64PublicKey(encryption.publicKey));
oos.flush();
// read sharedKey
String encodedKey = ois.readUTF();
encryption.setSharedKey(encryption.decodeBase64PublicKey(encodedKey, "RSA"));
} catch (Exception e) {
e.printStackTrace();
}
}
public Connection(Socket connection, String encryptionMethod) {
try {
//this.connection = connection;
this.ois = new ObjectInputStream(connection.getInputStream());
this.oos = new ObjectOutputStream(connection.getOutputStream());
encryption = AsymmetricalEncryptionFactory.getAsymmetricalEncryption(encryptionMethod);
// sending the public key
oos.writeUTF(encryption.encodeBase64PublicKey(encryption.publicKey));
oos.flush();
// read sharedKey
String encodedKey = ois.readUTF();
encryption.setSharedKey(encryption.decodeBase64PublicKey(encodedKey, encryptionMethod));
} catch (Exception e) {
e.printStackTrace();
}
}
public Response request(Request request){
try {
byte[] encryptedStringResponse = encryption.encrypt(request.toJSONString());
oos.write(encryptedStringResponse);
oos.flush();
byte[] response = ois.readAllBytes();
response = encryption.decrypt(response);
return new Response(new JSONObject(new String(response)));
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}
At the moment i don't know why but when i send data from client to server the server says that a new connection has come but hangs on doing nothing while in the client side it says that the data has been sent.