Hope someone can see my issue. I'm trying to send encrypted data over the network using CipherOutputStream/CipherInputStream
and keep on getting BadPaddingException
. I use the same RSA keys for both sides and can manually encrypt/decrypt fine. The modulus for both private and public keys match.
This is the working example that manually encrypt/decrypt using Cipher
and the keys.
public static void main(String[] args) {
PrintStream out = System.out;
try {
PrivateKey pri_key = Util.readPrivateKey("data/private.der");
PublicKey pub_key = Util.readPublicKey("data/public.der");
Cipher cipher = Cipher.getInstance("RSA/ECB/OAEPWithSHA1AndMGF1Padding");
String hi = "Hello World";
byte[] data = hi.getBytes("UTF8");
out.println("data[" + data.length + "]");
cipher.init(Cipher.ENCRYPT_MODE, pub_key);
byte[] encdata = cipher.doFinal(data);
out.println("encdata[" + encdata.length + "]");
cipher.init(Cipher.DECRYPT_MODE, pri_key);
byte[] decdata = cipher.doFinal(encdata);
out.println("decdata[" + decdata.length + "]");
out.println(new String(decdata, "UTF8"));
} catch (Exception e) {
e.printStackTrace();
}
}
The send/receive codes that does the encrypt/decrypt
static class ByteEncComm extends Comm {
public ByteEncComm(Socket sock, PrivateKey priv_key, PublicKey pub_key) {
super(sock, priv_key, pub_key);
}
public void send(Bird b) {
try {
Cipher cipher = Cipher.getInstance("RSA/ECB/OAEPWithSHA1AndMGF1Padding");
cipher.init(Cipher.ENCRYPT_MODE, public_key);
byte[] data = "Hello World".getBytes("UTF8");
CipherOutputStream cos = new CipherOutputStream(sock.getOutputStream(), cipher);
cos.write(data, 0, data.length);
cos.flush();
out.println("Sent data[" + data.length + "]");
} catch (Exception e) {
e.printStackTrace();
}
}
public Bird receive() {
PrintStream out = System.out;
try {
Cipher cipher = Cipher.getInstance("RSA/ECB/OAEPWithSHA1AndMGF1Padding");
cipher.init(Cipher.DECRYPT_MODE, private_key);
CipherInputStream cis = new CipherInputStream(sock.getInputStream(), cipher);
out.println("Avail " + cis.available());
byte[] data = cis.readAllBytes();
out.println("Got data[" + data.length + "]");
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}
Client Code:
public class Client {
public static void main(String[] args) {
PrintStream out = System.out;
try {
PrivateKey pri_key = Util.readPrivateKey("data/private.der");
PublicKey pub_key = Util.readPublicKey("data/public.der");
Socket sock = new Socket("127.0.0.1", 5555);
Comm comm = new Comm.ByteEncComm(sock, pri_key, pub_key);
comm.send(new Bird("Robin"));
sock.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
Server code:
public class Server extends Thread {
public static void main(String[] args) {
PrintStream out = System.out;
try {
PrivateKey pri_key = Util.readPrivateKey("data/private.der");
PublicKey pub_key = Util.readPublicKey("data/public.der");
ServerSocket serversock = new ServerSocket(5555);
Socket sock = serversock.accept();
Comm comm = new Comm.ByteEncComm(sock, pri_key, pub_key);
comm.receive();
sock.close();
serversock.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
Error:
java.io.IOException: javax.crypto.BadPaddingException: Decryption error
at java.base/javax.crypto.CipherInputStream.getMoreData(CipherInputStream.java:148)
at java.base/javax.crypto.CipherInputStream.read(CipherInputStream.java:261)
at java.base/java.io.InputStream.readNBytes(InputStream.java:409)
at java.base/java.io.InputStream.readAllBytes(InputStream.java:346)
at foo.enc.Comm$ByteEncComm.receive(Comm.java:139)
at foo.enc.Server.main(Server.java:21)
Caused by: javax.crypto.BadPaddingException: Decryption error
at java.base/sun.security.rsa.RSAPadding.unpadOAEP(RSAPadding.java:488)
at java.base/sun.security.rsa.RSAPadding.unpad(RSAPadding.java:284)
at java.base/com.sun.crypto.provider.RSACipher.doFinal(RSACipher.java:372)
at java.base/com.sun.crypto.provider.RSACipher.engineDoFinal(RSACipher.java:418)
at java.base/javax.crypto.Cipher.doFinal(Cipher.java:2152)
at java.base/javax.crypto.CipherInputStream.getMoreData(CipherInputStream.java:145)
... 5 more