简体   繁体   中英

Encrypted socket connection java using RSA (IllegalArgumentException: Illegal base64 character 10)

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.

The best way to do this is to use TLS. In Java, you can create server and client socket factories through an SSLContext .

It would be .nethical to try to devise your own cryptosystem and apply it to any data that other people are trusting you to secure. But if you are doing this for fun, as a learning exercise, and don't intend to do any real work with it, you can make the most of your effort by trying to learn how real cryptosystems work.

RSA is relatively slow, and the amount of data that can be encrypted in each operation is limited by the RSA key size that you choose. It is best used to encrypt another key for a symmetric cipher like AES. This is how RSA is used in any widely accepted encryption scheme. Large amounts of application data can then encrypted quickly with the symmetric cipher, using a key exchanged via RSA.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM