This week's book giveaway is in the Servlets forum.
We're giving away four copies of Murach's Java Servlets and JSP and have Joel Murach on-line!
See this thread for details.
The moose likes Java in General and the fly likes [SOLVED] Java Decryption returning only whitespace Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


Win a copy of Murach's Java Servlets and JSP this week in the Servlets forum!
JavaRanch » Java Forums » Java » Java in General
Bookmark "[SOLVED] Java Decryption returning only whitespace" Watch "[SOLVED] Java Decryption returning only whitespace" New topic
Author

[SOLVED] Java Decryption returning only whitespace

Joris Bolsens
Greenhorn

Joined: Jul 07, 2013
Posts: 16
Hello all, I made an account here because I could not find a solution to my problem. I believe the problem lies in my comunication with server, not the decryption itself.
I am trying to make a simple chat type program which encryptes all messages using AES, sends to server, server sends back, client decrypts and updates the message area.

Also, if you have suggestions on how to improve this, please do let me know
anyway, here is what I have so far:

encryption/decryption


Client side


and my server listener (just an echo atm)


I have been looking at this for quite some time now and have no idea what is wrong. Have tried multiple things but I get either this same error or others.

Many thanks to all who help out.
Joris Bolsens
Greenhorn

Joined: Jul 07, 2013
Posts: 16
looks like the problem lies somwhere in converting the string recieved from server back into a byte[]

the input here matches the encrypted string I sent the server, but they byte[] does not match the original byte[] given from processor.crypt(String in)
Jesper de Jong
Java Cowboy
Saloon Keeper

Joined: Aug 16, 2005
Posts: 14074
    
  16

I haven't looked at your program in detail, but the following might be an issue.

Strings consist of characters. Characters are represented in the computer's memory by numbers - stored as bytes. Exactly what number represents what character, is determined by the character encoding that you use. There are a number of standard character encodings, for example ASCII, ISO-8859-1 and UTF-8 are common ones.

When you convert characters to bytes or vice versa, you do so according to a character encoding.

When you call getBytes() on a string or create a new string from a byte[], and you don't specify the character encoding, then the default character encoding of your operating system is used. If the character encoding that the server uses differs from the default character encoding of the client, then the bytes or the string will differ between server and client, leading to errors.

So, it's best to always specify the character encoding, instead of relying on the default. For example:


Java Beginners FAQ - JavaRanch SCJP FAQ - The Java Tutorial - Java SE 7 API documentation
Scala Notes - My blog about Scala
Joris Bolsens
Greenhorn

Joined: Jul 07, 2013
Posts: 16
Jesper de Jong wrote:I haven't looked at your program in detail, but the following might be an issue.

Strings consist of characters. Characters are represented in the computer's memory by numbers - stored as bytes. Exactly what number represents what character, is determined by the character encoding that you use. There are a number of standard character encodings, for example ASCII, ISO-8859-1 and UTF-8 are common ones.

When you convert characters to bytes or vice versa, you do so according to a character encoding.

When you call getBytes() on a string or create a new string from a byte[], and you don't specify the character encoding, then the default character encoding of your operating system is used. If the character encoding that the server uses differs from the default character encoding of the client, then the bytes or the string will differ between server and client, leading to errors.

So, it's best to always specify the character encoding, instead of relying on the default. For example:



Thought of that shortly after posting, should have updated but that did not work either. :/
Tony Docherty
Bartender

Joined: Aug 07, 2007
Posts: 2170
    
  47
I would start by removing the encryption/decryption part so you are sending plain text converted to a byte stream. That way you can totally rule out encryption/decryption rather than assuming it's not the problem.
Secondly dump to the screen the contents of byte array as you send it and as you receive it and check you get exactly the same byte values, order and length on both machines.
Joris Bolsens
Greenhorn

Joined: Jul 07, 2013
Posts: 16
Tony Docherty wrote:I would start by removing the encryption/decryption part so you are sending plain text converted to a byte stream. That way you can totally rule out encryption/decryption rather than assuming it's not the problem.
Secondly dump to the screen the contents of byte array as you send it and as you receive it and check you get exactly the same byte values, order and length on both machines.


I am converting the string to a byte[] encrypting, converting back to a string, sending to server which just echos back to client. Client then converts string back to byte[] decrypts, converts to string and updates message area. I know I am making it way more complicated than it should, But I could not get the DataInput/Output streams to send bytes correctly.
I tried doing it like this:
http://stackoverflow.com/questions/2878867/how-to-send-an-array-of-bytes-over-a-tcp-connection-java-programming

but I got an out of memory exception

Just now tried bypassing the whole string -> byte[] -> string -> byte[] -> string thing (no encryption) and that works.

So here is what I got so far:
Working:
Sending/recieving Strings
updating message area

not Working:
string -> byte[] -> string -> byte[] -> string
Encryption/decrption
Joris Bolsens
Greenhorn

Joined: Jul 07, 2013
Posts: 16
Found problem, no Idea what is causing it though. When I do string -> byte[] -> string -> byte[] -> string
I tried printing out the byte[] right after encryption and right before decryption using Arrays.toString(byte[]);
The two are very different:
post encryption: [-7, -114, -86, 81, -88, -121, -69, -89, 116, 94, -24, -46, 63, -99, -29, 126]
pre decryption: [63, 81, 63, 63, 63, 63, 116, 94, 63, 63, 63, 63, 63]


I made sure to specify UTF-8 as the encoding everywhere, here is the string that it seems to be sending to server (very different from when I did not specify utf-8)
?Q???t^???

This is leading me to believe that there is some sort of problem using UTF-8
Will try some different encodings and get back



EDIT
Just tried using my system default encoding and results where much more simliar, except for one little part:

[-7, -114, -86, 81, -88, -121, -69, -89, 116, 94, -24, -46, 63, -99, -29, 126]

[-7, -114, -86, 81, -88, -121, -69, -89, 116, 94, -24, -46, 63, 63, -29, 126]

I don't see how 1 byte can be the difference between whitespace and text though
will try some other encodings
Ulf Dittmer
Marshal

Joined: Mar 22, 2005
Posts: 41089
    
  44
+1 on what Jesper said. Rule of thumb: never, ever, use "new String(byte[])" or "String.getBytes()". If you know that it's going to be ASCII, say so in the code via the encoding parameter.

And when dealing with encryption: once something is encrypted, it is no longer character data, and thus can't be stored in a String object. You need to use a byte[]. If for some reason you need to store and transfer it as a String, then you need to base-64 encode the byte[] - that makes it an ASCII String.

(Edit: posted before seeing your last post)


Ping & DNS - my free Android networking tools app
Henry Wong
author
Sheriff

Joined: Sep 28, 2004
Posts: 18509
    
  40

Joris Bolsens wrote:
I am converting the string to a byte[] encrypting, converting back to a string, sending to server which just echos back to client.



What do you mean by "converting back to data"? The output from encryption is binary data -- it can't be converted back to a string via a new String() call. You have to encode it -- examples include uuencode or base64 encode.

In other words, you can't treat binary data as text.

Henry


[EDIT: looks like I was beaten to the solution by a few people, including the OP]

Books: Java Threads, 3rd Edition, Jini in a Nutshell, and Java Gems (contributor)
Joris Bolsens
Greenhorn

Joined: Jul 07, 2013
Posts: 16
Ulf Dittmer wrote:+1 on what Jesper said. Rule of thumb: never, ever, use "new String(byte[])" or "String.getBytes()". If you know that it's going to be ASCII, say so in the code via the encoding parameter.

And when dealing with encryption: once something is encrypted, it is no longer character data, and thus can't be stored in a String object. You need to use a byte[]. If for some reason you need to store and transfer it as a String, then you need to base-64 encode the byte[] - that makes it an ASCII String.

(Edit: posted before seeing your last post)


So rather than specifying something like UTF-8 I should sent to ASCII?
or is this a whole different process to base-64 encode? (kind of new to the whole encryption thing in case you haven't noticed xD )
Ulf Dittmer
Marshal

Joined: Mar 22, 2005
Posts: 41089
    
  44
Yes, these are two different issues, and you need to get both right.

Base-64 encoding is not an encoding that you can use as parameter for "new String(byte[], String)" or "String.getBytes(String)". It knows nothing about character data (in the sense that ASCII or UTF-8 do), it merely lets you store binary data (like a byte[]) as a string (which makes it easier to transfer, because transporting ASCII over the net generally causes fewer issues that transporting 8-bit character data, or way fewer issues than transporting binary data like a byte[], which can create havoc in various ways). The Apache Commons Codec library can be used for base-64 en- and decoding.
Joris Bolsens
Greenhorn

Joined: Jul 07, 2013
Posts: 16
I figured it out, am using the spring framework base64 encryption thing.

Thanks all for the help. I thought that encrypted just sent it through a fancy algo thing and did not know it made it into binary data.
marking as solved
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: [SOLVED] Java Decryption returning only whitespace
 
Similar Threads
Connection Refused Error
Socket : MultiClient Server
data lenght mismatch in socket code
Read, Send, Write a File through a socket
URGENT: Transferring Zip Files