所以我有一个服务器端公钥和私钥,我的目的是向客户端发送公钥,客户端将使用密钥加密字符串,然后通过流发送字节,服务器将解密字节数组 .
例外:
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();
2 回答
如果您正在使用ObjectOutputStream,为什么还要使用getEncoded将公钥转换为字节数组呢?您可以直接序列化对象 . 例如 . handler.getOos()的writeObject(公钥);或者,如果必须使用编码版本,则删除ObjectOutputStream并使用ByteArrayOutputStream .
问题是您使用
DataInputStream.available()
来确定要读取的字节数 . 那种方法没有做你明显认为它做的事情 .从这个方法的Javadoc:
它只返回可以读取的字节数 without blocking ,它可以远远小于您发送的实际字节数,特别是如果您使用网络套接字发送/接收该数据 .
解决方案:
在写入字节之前,使用包含您正在编写的字节数的
writeInt
方法写入int
在读取字节之前,调用
readInt
以读取将跟随的字节数,并从该数字构造一个正确长度的字节数组 .