Java 从套接字中的objectStreams发送公钥的正确方法?

Java 从套接字中的objectStreams发送公钥的正确方法?,java,sockets,encryption,Java,Sockets,Encryption,我使用RSA算法来加密/解密客户端和服务器之间的消息,但在此之前,我需要交换它们的公钥,因为我希望它们每个都有自己的公钥对,在交换之后,我使用相反的公钥加密并发送消息。我的问题在于我交换钥匙的时候。这是我的交换部分: 服务器: ObjectOutputStream obOut = new ObjectOutputStream(socket.getOutputStream()); ObjectInputStream obIn = new ObjectInputStream(socket.getIn

我使用RSA算法来加密/解密客户端和服务器之间的消息,但在此之前,我需要交换它们的公钥,因为我希望它们每个都有自己的公钥对,在交换之后,我使用相反的公钥加密并发送消息。我的问题在于我交换钥匙的时候。这是我的交换部分:

服务器:

ObjectOutputStream obOut = new ObjectOutputStream(socket.getOutputStream());
ObjectInputStream obIn = new ObjectInputStream(socket.getInputStream());

obOut.writeObject(publicKey);
obOut.flush();
Object obj = obIn.readObject();
otherPublicKey = (PublicKey) obj;
ObjectOutputStream obOut = new ObjectOutputStream(socket.getOutputStream());
ObjectInputStream obIn = new ObjectInputStream(socket.getInputStream());

Object obj = obIn.readObject();
otherPublicKey = (PublicKey)obj;
obOut.writeObject(publicKey);
obOut.flush();
客户:

ObjectOutputStream obOut = new ObjectOutputStream(socket.getOutputStream());
ObjectInputStream obIn = new ObjectInputStream(socket.getInputStream());

obOut.writeObject(publicKey);
obOut.flush();
Object obj = obIn.readObject();
otherPublicKey = (PublicKey) obj;
ObjectOutputStream obOut = new ObjectOutputStream(socket.getOutputStream());
ObjectInputStream obIn = new ObjectInputStream(socket.getInputStream());

obOut.writeObject(publicKey);
obOut.flush();
Object obj = obIn.readObject();
otherPublicKey = (PublicKey) obj;
例外情况:

javax.crypto.BadPaddingException: Data must start with zero

at sun.security.rsa.RSAPadding.unpadV15(RSAPadding.java:325)
at sun.security.rsa.RSAPadding.unpad(RSAPadding.java:272)
at com.sun.crypto.provider.RSACipher.doFinal(RSACipher.java:356)
at com.sun.crypto.provider.RSACipher.engineDoFinal(RSACipher.java:382)
at javax.crypto.Cipher.doFinal(Cipher.java:2086)
我知道我的错误可能是当我将对象投射到PublicKey时。所以我的问题是什么是更合适的方法来做这件事

编辑:

忘了提及我使用此RSA算法进行加密/解密:

public static String encryptWithPublicKey(byte[] message, PublicKey publicKey) throws Exception {
    PublicKey apiPublicKey = publicKey;
    Cipher rsaCipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
    rsaCipher.init(Cipher.ENCRYPT_MODE, apiPublicKey);
    byte[] encVal = rsaCipher.doFinal(message);
    String encryptedValue = new BASE64Encoder().encode(encVal);
    return encryptedValue;
}

public static String decryptWithPrivateKey(byte[] message, PrivateKey privateKey) throws Exception {
    PrivateKey pKey = privateKey;
    Cipher rsaCipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
    rsaCipher.init(Cipher.DECRYPT_MODE, pKey);
    byte[] decVal = rsaCipher.doFinal(message);
    String decryptedValue = new String(decVal);
    return decryptedValue;
}

我会改变它,让它看起来像这样,看看这是否有帮助

客户:

ObjectOutputStream obOut = new ObjectOutputStream(socket.getOutputStream());
ObjectInputStream obIn = new ObjectInputStream(socket.getInputStream());

obOut.writeObject(publicKey);
obOut.flush();
Object obj = obIn.readObject();
otherPublicKey = (PublicKey) obj;
ObjectOutputStream obOut = new ObjectOutputStream(socket.getOutputStream());
ObjectInputStream obIn = new ObjectInputStream(socket.getInputStream());

obOut.writeObject(publicKey);
obOut.flush();
Object obj = obIn.readObject();
otherPublicKey = (PublicKey) obj;
服务器:

ObjectOutputStream obOut = new ObjectOutputStream(socket.getOutputStream());
ObjectInputStream obIn = new ObjectInputStream(socket.getInputStream());

obOut.writeObject(publicKey);
obOut.flush();
Object obj = obIn.readObject();
otherPublicKey = (PublicKey) obj;
ObjectOutputStream obOut = new ObjectOutputStream(socket.getOutputStream());
ObjectInputStream obIn = new ObjectInputStream(socket.getInputStream());

Object obj = obIn.readObject();
otherPublicKey = (PublicKey)obj;
obOut.writeObject(publicKey);
obOut.flush();

如果这是所有相关的代码,那么您是base64编码,而不是base64解码。

只是想说出来,问题可能不是强制转换。我使用
Object*Streams
,我使用不同的类来分类。铸造不应该是个问题。好吧,我试了一些事情之后。问题是我想使用流进行持续的通信,基本上我正在建立一个聊天室。我读过objectoutput首先从objectinput开始,但是我的代码中有一部分我只需要输入,它被卡在那里,现在我没有得到任何结果。我希望这只是一个练习,不要在任何地方部署这个坏掉的协议。它对中间人攻击、重播、选择密文攻击等不安全。只需使用TLS.XY问题。您没有提供任何证据表明问题出在密钥交换中。序列化不会损坏数据。问题在于您的加密代码、解密代码或您未看到(或可能丢失)的base64解码。。。注意:由于原始消息是字节[],因此解密方法应返回字节[],而不是字符串。保持对称。字节[]可以是二进制的,字符串不是二进制数据的容器。不,我确实拿回了密钥。我的问题是我无法使用它,因为我认为我在某个地方失去了精度。后来我用它来加密解密,现在我的输入流就在那里不停地读着@∏αναγιώτηςΝκολαρόποολος定义“某处失去精度”。你是说序列化会神秘地丢失数据吗?为什么?怎么做?你的证据呢?@3kings你为什么这么说?它打算解决什么问题?