java - 使用 RSA 的加密套接字连接 java(IllegalArgumentException : Illegal base64 character 10)

标签 java sockets encryption encoding rsa

所以我正在构建一个java应用程序,它使用安全的RSA连接来传递数据(目前我正在手动编码加密/解密技术,如果有库或更好的方法可以做到这一点,请随意编写) ,这是我第一次这样做,所以我对这个主题不太了解。

这是我在服务器和客户端上使用的用于加密/解密的类:

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;
    }

}

RSAEncryption 类非对称加密,因为我希望将来实现不同的加密协议(protocol)。 这是服务器端连接:

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);
        }
    }

}

这是客户端连接:

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;
    }

}

目前我不知道为什么,但是当我从客户端向服务器发送数据时,服务器说已经有一个新连接,但在客户端却什么也不做,它说数据已发送。

最佳答案

执行此操作的最佳方法是使用 TLS。在Java中,您可以创建服务器和客户端套接字工厂through an SSLContext.

尝试设计自己的密码系统并将其应用于其他人信任您保护的任何数据是不道德的。但是,如果您这样做是为了好玩,作为学习练习,并且不打算用它做任何实际工作,那么您可以通过尝试了解真正的密码系统如何工作来充分利用您的努力。

RSA 相对较慢,并且每次操作中可以加密的数据量受到您选择的 RSA key 大小的限制。是best used to encrypt another key对于像 AES 这样的对称密码。这就是 RSA 在任何广泛接受的加密方案中的使用方式。然后,可以使用通过 RSA 交换的 key ,通过对称密码快速加密大量应用程序数据。

关于java - 使用 RSA 的加密套接字连接 java(IllegalArgumentException : Illegal base64 character 10),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64294303/

相关文章:

java - 在从类构造函数调用的方法中初始化最终变量

java - "new"表达式中的花括号? (例如 "new MyClass() { ... }")

java - 可能的原因可能是在应用程序未配置安全时调用 https

c# - C#:远程主机上的套接字ReceiveAsync和SendAsync出现问题

python - 在 Python 中的 sock.sendall() 之后调用 sock.recv()

java - 为什么 Integer.parseInt 在没有 try catch 的情况下进行编译?

c - sigset_t 在这种情况下有用吗?

linux - 使用 Ansible 自动设置加密分区

java - gpg --list-keys 为空但文件解密 bouncycaSTLe 加密文件

encryption - 使用 RSA-1024 签名 SHA-256 摘要 : what is the size?