Restnom
Restnom

Reputation: 134

AES decryption after sending message to IP address

So I am making an app that sends secure messages to the specified IP address. I am using AES to encrypt the message and that part works great. I am able to encrypt the message and also decrypt it before I send the message. However, when I try to decrypt a message that has been recieved from the server, I can not decrypt it. It gets displayed in it's encrypted form.

I get this error "java.lang.NumberFormatException: Invalid int: "ne"" and I think it may have to do with the character encoding or something? Is a string altered in any way when it is sent over a network?

Here are snippets that may be related to the issue.

public static String encrypt(String seed, String cleartext)
        throws Exception {
    byte[] rawKey = getRawKey(seed.getBytes());
    byte[] result = encrypt(rawKey, cleartext.getBytes());
    return toHex(result);
}

public static String decrypt(String seed, String encrypted)
        throws Exception {
    byte[] rawKey = getRawKey(seed.getBytes());
    byte[] enc = toByte(encrypted);
    byte[] result = decrypt(rawKey, enc);
    return new String(result);
}


public static byte[] toByte(String hexString) {
    int len = hexString.length() / 2;
    byte[] result = new byte[len];
    for (int i = 0; i < len; i++)
        result[i] = Integer.valueOf(hexString.substring(2 * i, 2 * i + 2),
                16).byteValue();
    return result;
}

public static String toHex(byte[] buf) {
    if (buf == null)
        return "";
    StringBuffer result = new StringBuffer(2 * buf.length);
    for (int i = 0; i < buf.length; i++) {
        appendHex(result, buf[i]);
    }
    return result.toString();
}

This is where I do the decryption for the message to be displayed.

while (!goOut) {
    if (dataInputStream.available() > 0) {
        incoming = dataInputStream.readUTF();

        if(encrypt == true) {
            try{
                msgLog += AESHelper.decrypt(seed,incoming);
            } catch (Exception e) {
                e.printStackTrace();
            }

        } else msgLog += incoming;



        MainActivity.this.runOnUiThread(new Runnable() {

            @Override
            public void run() {
                chatMsg.setText(msgLog);
            }
        });

This is encrypting the message:

OnClickListener buttonEncryptOnClickListener = new OnClickListener()   {
        public void onClick(View v) {
            if (chatClientThread == null) {
                return;
            }
            if (editTextSay.getText().toString().equals("")) {
                return;
            }

            if(!editTextSay.getText().toString().equals("")){

                String message = editTextSay.getText().toString();
                encrypt = true;
                int secLvl = Integer.parseInt(editTextSecurity.getText().toString());

                String encryptedMsg;
                try {
                     encryptedMsg = AESHelper.encrypt(seed, message);
                    textEncryptedmsg.setText(encryptedMsg);
                    textEncryptedmsg.setVisibility(View.VISIBLE);

                } catch (Exception e) {
                    e.printStackTrace();

                }

            }

        }
    };

This is sending the message:

OnClickListener buttonSendOnClickListener = new OnClickListener() {

        @Override
        public void onClick(View v) {
            if (editTextSay.getText().toString().equals("")) {
                return;
            }

            if(chatClientThread==null){
                return;
            }

            if (encrypt == true){

                chatClientThread.sendMsg(textEncryptedmsg.getText().toString() + "\n");
            } else {
                chatClientThread.sendMsg(editTextSay.getText().toString() + "\n");
            }

            editTextSay.setText("");
            textEncryptedmsg.setText("");
            textDecryptedmsg.setText("");
            encrypt = false;
            incomingmsg.setVisibility(View.VISIBLE);
        }

    };

Upvotes: 0

Views: 331

Answers (2)

Restnom
Restnom

Reputation: 134

I found a way around the issue without using CipherInputStream. Whenever I encrypted a message and sent it, the encryption/decryption algorithm would not decrypt the message received from the server. Since the output encrypted message was identical to what I sent, I printed the incoming encrypted message into a TextView then I copied the TextView into a String and decrypted it and it works great now.

 while (!goOut) {


            if (dataInputStream.available() > 0) {

                final String incoming = dataInputStream.readUTF();



                MainActivity.this.runOnUiThread(new Runnable() {

                    @Override
                    public void run() {

                        incomingmsg.setText(incoming);
                        mustDecrypt = incomingmsg.getText().toString();



                        if (encrypt)
                            try {
                                mustDecrypt = AESHelper.decrypt(seed, mustDecrypt);
                                msgLog += mustDecrypt;

                            } catch (Exception e){
                                e.printStackTrace();
                            }
                            else msgLog += mustDecrypt;




                        chatMsg.setText(msgLog);
                    }
                });
            }

Upvotes: 0

Artjom B.
Artjom B.

Reputation: 61892

I'll assume that you're sending the ciphertext in a hex encoded form. DataInputStream#readUTF() reads a single Unicode character from the stream. Since you're sending hex characters this will mean that a single ciphertext byte can be constructed from two of such Unicode characters.

The problem is that AES operates on blocks. Trying to decrypt every single "half"-byte separately won't work.

You will need to rewrite the decryption method to either

  • use streaming decryption or
  • read the whole ciphertext and decrypt in one go.

If you want to try streaming decryption, then you have basically two options:


Here is an (pseudo-code) example of reading the whole thing before trying to decrypt it:

StringBuilder incoming = new StringBuilder();
while (!goOut && ) {
    incoming.append(dataInputStream.readUTF());
}
if(encrypt == true) {
    try{
        msgLog += AESHelper.decrypt(seed, incoming.toString());
    } catch (Exception e) {
        e.printStackTrace();
    }
} else msgLog += incoming;

Upvotes: 1

Related Questions