所以我有一个服务器端公钥和私钥,我的目的是向客户端发送公钥,客户端将使用密钥加密字符串,然后通过流发送字节,服务器将解密字节数组。
例外:
javax.crypto.BadPaddingException:解密错误
代码:
发送编码密钥。
handler.getOos().writeObject(publicKey.getEncoded());
handler.getOos().flush();
接收(编码密钥的)字节数组:
Object o = ois.readObject();
if (o instanceof byte[]) {
JChat.get().setServerPublicKey(KeyFactory.getInstance("RSA").generatePublic(new X509EncodedKeySpec((byte[]) o)));
JChat.get().go();
}
go()方法(这里我使用DataOutputStream发送字节数组):
public void go() {
String text = "hello darkness my old friend";
byte[] encrypted = encrypt(text, serverPublicKey);
try {
handler.getDos().write(encrypted);
handler.getDos().flush();
} catch (IOException e) {
e.printStackTrace();
}
}
在服务器端读取字节数组:
int count = dis.available();
byte[] in = new byte[count];
dis.readFully(in);
System.out.println(Server.decrypt(in, Server.get().getPrivateKey()));
解密方法抛出此异常:
javax.crypto.BadPaddingException: Decryption error
at sun.security.rsa.RSAPadding.unpadV15(RSAPadding.java:380)
at sun.security.rsa.RSAPadding.unpad(RSAPadding.java:291)
at com.sun.crypto.provider.RSACipher.doFinal(RSACipher.java:363)
at com.sun.crypto.provider.RSACipher.engineDoFinal(RSACipher.java:389)
at javax.crypto.Cipher.doFinal(Cipher.java:2165)
at com.archiepking.Server.decrypt(Server.java:97)
at com.archiepking.net.ClientHandler$1.run(ClientHandler.java:44)
at java.lang.Thread.run(Thread.java:745)
关于我做错了什么的任何建议?请注意:
Dos = DataOutputStream Dis = DataInputStream Oos = ObjectOutputStream Ois = ObjectInputStream
我使用两个不同的套接字,一个用于发送对象,另一个用于数据类型(因为我的聊天应用程序需要两个)。
我该怎么做才能解决此错误?
更多信息: 生成密钥:
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
keyPairGenerator.initialize(1024);
KeyPair keyPair = keyPairGenerator.genKeyPair();
byte[] publicKeyBytes = keyPair.getPublic().getEncoded();
FileOutputStream fosPublic = new FileOutputStream("public");
fosPublic.write(publicKeyBytes);
fosPublic.close();
byte[] privateKeyBytes = keyPair.getPrivate().getEncoded();
FileOutputStream fosPrivate = new FileOutputStream("private");
fosPrivate.write(privateKeyBytes);
fosPrivate.close();
publicKey = keyPair.getPublic();
privateKey = keyPair.getPrivate();
答案 0 :(得分:1)
问题是您使用DataInputStream.available()
来确定要读取的字节数。那个方法不会做你显然认为它做的事情。
从这个方法的Javadoc:
返回可读取的字节数的估计值(或 跳过此输入流而不会被下一个阻塞 此输入流的方法的调用者。下一个来电者可能是 相同的线程或另一个线程。单读或跳过这么多 字节不会阻塞,但可以读取或跳过更少的字节。
它只返回可以读取无阻塞的字节数,这可能远远小于您发送的实际字节数,特别是如果您使用网络套接字发送/接收那个数据。
解决方案:
int
方法编写writeInt
readInt
来读取将要跟随的字节数,并从该数字构造一个正确长度的字节数组。答案 1 :(得分:0)
如果您正在使用ObjectOutputStream,为什么还要使用getEncoded将公钥转换为字节数组呢?您可以直接序列化对象。例如 。handler.getOos()的writeObject(公钥); 或者,如果必须使用编码版本,则删除ObjectOutputStream并改为使用ByteArrayOutputStream。