0

I'm doing a small school "project" that is a small chat program. You start the server and the server sends a public key to the client so that the client can send back encrypted data.

The problem is that when I try to decrypt it on the server side I recieve a error.

javax.crypto.BadPaddingException: Decryption error
at sun.security.rsa.RSAPadding.unpadV15(RSAPadding.java:380)
at sun.security.rsa.RSAPadding.unpad(RSAPadding.java:291)

My server awaits for a socket.accept() and when a client connect it sends a public key to this socket.

(This is not the whole code)

private Client client;
private JSONObject json;

//Connector is used as a listener for messages.
public Connector(Socket socket, ServerBroadCast SBC) throws IOException {
    DIS = new DataInputStream(socket.getInputStream());        
    this.SBC = SBC;
    this.client = SBC.AddClient(socket);        
    //Sending public RSA key to client to use to encrypt their message
    this.client.sendPublicKey(RSA.getPublicKey()); //This is where I am sending RSA public key to client
}

I'm just sending one message back to server to see if it's encrypted and if the server can decrypt it.

Using this class to send to CLIENT

DataOutputStream DOS;
public Client(Socket s) throws IOException {
    DOS = new DataOutputStream(s.getOutputStream());
}
public void sendPublicKey(PublicKey publicKey) throws IOException {
    JSONObject json = new JSONObject();

    json.put(JSONKeys.TYPE, JSONTypes.PUBLIC_KEY);
    json.put(JSONKeys.MESSAGE, RSA.getEncodedPublicKey());
    this.send(json);
}

public void send(JSONObject json) throws IOException{
    this.DOS.writeUTF(json.toString());
    System.out.println(json);
}

And here is my RSA class to encrypt and decrypt

private static PrivateKey privateKey = null;
private static PublicKey publicKey = null;

public static void generateKeyPair() {
    KeyPairGenerator keyPairGenerator = null;
    KeyPair keyPair = null;

    try {
        keyPairGenerator = KeyPairGenerator.getInstance("RSA");
    } catch (NoSuchAlgorithmException e) {
        e.printStackTrace();
    }

    keyPairGenerator.initialize(1024);
    keyPair = keyPairGenerator.generateKeyPair();

    RSA.privateKey = keyPair.getPrivate();
    RSA.publicKey = keyPair.getPublic();
}

public static String getEncodedPublicKey() {
    return (new String(Base64.encode(RSA.getPublicKey().getEncoded())));
}

public static String encrypt(String string) {
    byte[] encrypted = null;

    try {
        Cipher cipher = Cipher.getInstance("RSA");//174 bytes

        cipher.init(Cipher.ENCRYPT_MODE, RSA.getPublicKey());
        encrypted = cipher.doFinal(string.getBytes());
    } catch (NoSuchAlgorithmException e) {
        e.printStackTrace();
    } catch (NoSuchPaddingException e) {
        e.printStackTrace();
    } catch (InvalidKeyException e) {
        e.printStackTrace();
    } catch (IllegalBlockSizeException e) {
        e.printStackTrace();
    } catch (BadPaddingException e) {
        e.printStackTrace();
    }

    return (new String(Base64.encode(encrypted)));
}

public static String decrypt(String string) {
    byte[] decrypted = null;

    try {
        Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");

        cipher.init(Cipher.DECRYPT_MODE, RSA.getPrivateKey());
        decrypted = cipher.doFinal(Base64.decode(string));
    } catch (InvalidKeyException e) {
        e.printStackTrace();
    } catch (NoSuchAlgorithmException e) {
        e.printStackTrace();
    } catch (NoSuchPaddingException e) {
        e.printStackTrace();
    } catch (IllegalBlockSizeException e) {
        e.printStackTrace();
    } catch (BadPaddingException e) {
        e.printStackTrace();
    } catch (Base64DecodingException e) {
        e.printStackTrace();
    }

    return (new String(decrypted));
}

I get that there is something "wrong" with my padding since the error says that but I don't understand what.

The length of what I get back from the clients encrypted message is 174 byte long. I've understood that it is to long, but why does it create such a huge encrypted message from my plain text.

private final String MESSAGE = "Hello from client side";
6
  • The only thing I can think of is that JSON may been ignoring some of the bytes (that don't fit in a string)..Try using Base64 to encode and decode the bytes. (Java has Base64 support through Base64.getEncoder() and Base64.get decoder()). (When sending the key I mean) Commented May 13, 2016 at 15:07
  • @Meguy26 Sorry forgot to add another function I had. I'm already encoding and decoding with Base64. Still recieving this error Commented May 13, 2016 at 15:10
  • What about when sending the key? Commented May 13, 2016 at 15:10
  • @Meguy26 public static String getEncodedPublicKey() { return (new String(Base64.encode(RSA.getPublicKey().getEncoded()))); } That is what I am using Commented May 13, 2016 at 15:11
  • Ahh, okay. I'm not sure then, does the encryption have to be RSA, because java's SSLSocket does encryption on its own. You'd probably have to use an anonymous TSL protocol though Commented May 13, 2016 at 15:14

1 Answer 1

1

It seems that you have two questions to answer:

a) Is the public key correct at the client?

b) Is the ciphertext correct at the server?

Try answering the questions separately. For example, you can try:

  1. Take the public key at the server, and encrypt a message "hello world". Then take the private key at the server, and decrypt the message. Did it work? Then...

  2. Take the ciphertext from #1 and hard-code it in the client, so that regardless of what the server sends to the client, the client sends this ciphertext, which is known to be correct, back to the server. Now, does the server decrypt it again?

If the server decrypts it fine, then you can:

  1. Take the public key from the server and encrypt some data (on the client). Now, decrypt the data using the private key, at the client. Does it decrypt?

  2. Ok so now, send the ciphertext to the server and decrypt it.

Limit the number of unknowns at each step. Can the server actually decrypt correct ciphertext (maybe it can't due to some mistake)? Can the client actually receive the correct public key? Can the client send the correct ciphertext?

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks.. I did what you said, and it turned out I didn't handle the recieving public key properly.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.