Charset encoding toString to getbyte [closed] - java

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 7 years ago.
Improve this question
the conversion string to byte and back are different. I use to encypt/decrypt des and when i recive a string by Server, the server make toString(),i make myString.getByte for decrypt. decrypt not working because Input length must be multiple of 8 when decrypting with padded cipher... anyone can help me. thank you.
Server:
String keySession=DesKeySession.toString();
String Message=keySessione+"1.1.1.1";
byte [] text=(Message).getBytes();
// Encrypt the text
byte[] textEncrypted = desCipher.doFinal(text);
String StringtextEncrypted = textEncrypted.toString();
OutLista.InsertTail(StringtextEncrypted);
//list to send client with all information
outToClient.writeObject(OutLista);
Client:
String mesage=listaFromServer.DeleteTail();
byte [] messaggioKab=(message).getBytes();
// Initialize the same cipher for decryption
desCipher.init(Cipher.DECRYPT_MODE, myDesKey);
// Decrypt the text
byte[] textDecrypted = desCipher.doFinal(messaggioKab);//error

There are two problems here:
You are not converting a byte array to a String correctly. You must use new String, not toString().
In C, you can use a string to hold bytes. In Java, you cannot, because not every byte will be a valid representation of a character.
Both problems are due to this line:
String StringtextEncrypted = textEncrypted.toString();
In Java, all primitive arrays directly extend java.lang.Object. Such arrays do not define a toString method, which means every primitive array inherits the toString method of Object, which for a byte array usually produces something like "[B#19de8a6f89".
For this reason, you cannot convert a byte array to a String using toString(). You must create a String directly:
String stringtextEncrypted = new String(textEncrypted);
However, this is not safe unless you know your bytes actually represent characters encoded with a Charset. Your bytes are not encoded in a charset—they are the result of an encryption operation. It is never safe to store arbitrary bytes in a String as one might do in C, because the bytes may contain invalid sequences according to the charset used to decode them, and such invalid sequences will be automatically replaced with a designated "invalid sequence" character like ? or � in the new String.
(The actual charset used is the platform's default charset, since you didn't specify one explicitly; that is another issue with your code, since the client and server may not have the same default charset, but the above problems need to be corrected first.)
Simply put, you cannot safely use a String to hold your encrypted bytes. However, since byte[] is a subclass of Object, you can always put the encrypted byte array itself in your list. All primitive arrays are serializable.
By the way, the convention in Java is for all variable names and method names to start with a lowercase letter (except static final variables, which are usually constants). You should use names like message, insertTail and deleteTail.

Related

Base64 binary data type in java

I need to attach a Base64 binary element to a SOAP message...Im doing a dry run to check if I can convert a value read from a file into Base64 binary..
Here is the below code..In the last line I try to print the type of encoded1(I assume it should be Base64 binary values) but I get the following display..."Attachment[B"...How can I confirm if its Base64 binary string?
Path path = Paths.get("c:/tomcatupload/text.csv");
byte[] attachment1 = Files.readAllBytes(path);
byte[] encoded1 = Base64.encode(attachment1);
System.out.println("Attachment"+ encoded1.getClass().getName());
Base-64 encoding is a way to convert arbitrary bytes to bytes that fit in a range of text characters in ASCII encoding. This is done without any interpretation whatsoever - raw bytes are converted to base-64 on sender's end; the receiver converts them back to a stream of bytes, and that's all there is to it.
When your code prints encoded1.getClass().getName(), all it gets is the static type of the byte array. In order to interpret the data encoded in base-64 as something meaningful to your program, you need to know the format of underlying data transported as base-64. Once the bytes are delivered to you (in your case, that's encoded1 array of bytes) you need to decide what's inside, and act accordingly.
For example, if a serialized Java object is sent to you as base-64, you need to take encoded1, make an in-memory stream from it, and read the object using the regular serialization mechanism:
ByteArrayInputStream memStream = new ByteArrayInputStream(encoded1);
ObjectInputStream objStream = new ObjectInputStream(memStream);
Object attachedObject = objStream.readObject();
The encoding by Base64.encode() was successful if and only if size of encoded1 > size of obtained attachment1.
Please refer, to understand how the encoding works.
http://en.wikipedia.org/wiki/Base64
By the way, your last statement doesn't print the array content. It prints the name of the class to which encoded1 belongs to.

Best way for transfering files via socket in java

I have a BufferedReader object and a PrintWriter object. So I can work passing String objects made by json-io of any type (e.g.: List, Map, MyOwnClass)
My class have a byte[] attribute, this byte[] will keep a file bytes, such as an image.
The json generated of my class is very very big, obviously... Then i started to think that must have a better way to transfer files.
Should I change all the mechanism to transfer only byte[] instead of String? Does someone know what is the mechanism used by chat programs? Should I reserve the first 20 bytes of the array for the message identification?
I would write it to the socket in binary:
Assuming a class with one String and one byte[].
The String
The length of the String is written with DataOutputStream.writeInt(int) (or methods for smaller integers) and then OutputStream.write(byte[]) on the return value of String.getBytes(String) with the charset explicitly specified.
The byte[]
The length is written with DataOutputStream.writeInt(int) (or methods for smaller integers) and then OutputStream.write(byte[]) for the byte[] to transfer.
On the other side you would do the exact opposite of this procedure.
I chose this binary approach over JSON because even though you could transmit the byte[] with JSON almost as efficiently as in binary, it would defeat the very purpose of JSON: being human-readable.

How to convert byte array in String format to byte array?

I have created a byte array of a file.
FileInputStream fileInputStream=null;
File file = new File("/home/user/Desktop/myfile.pdf");
byte[] bFile = new byte[(int) file.length()];
try {
fileInputStream = new FileInputStream(file);
fileInputStream.read(bFile);
fileInputStream.close();
}catch(Exception e){
e.printStackTrace();
}
Now,I have one API, which is expecting a json input, there I have to put the above byte array in String format. And after reading the byte array in string format, I need to convert it back to byte array again.
So, help me to find;
1) How to convert byte array to String and then back to the same byte array?
The general problem of byte[] <-> String conversion is easily solved once you know the actual character set (encoding) that has been used to "serialize" a given text to a byte stream, or which is needed by the peer component to accept a given byte stream as text input - see the perfectly valid answers already given on this. I've seen a lot of problems due to lack of understanding character sets (and text encoding in general) in enterprise java projects even with experienced software developers, so I really suggest diving into this quite interesting topic. It is generally key to keep the character encoding information as some sort of "meta" information with your binary data if it represents text in some way. Hence the header in, for example, XML files, or even suffixes as parts of file names as it is sometimes seen with Apache htdocs contents etc., not to mention filesystem-specific ways to add any kind of metadata to files. Also, when communicating via, say, http, the Content-Type header fields often contain additional charset information to allow for correct interpretation of the actual Contents.
However, since in your example you read a PDF file, I'm not sure if you can actually expect pure text data anyway, regardless of any character encoding.
So in this case - depending on the rest of the application you're working on - you may want to transfer binary data within a JSON string. A common way to do so is to convert the binary data to Base64 and, once transferred, recover the binary data from the received Base64 string.
How do I convert a byte array to Base64 in Java?
is a good starting point for such a task.
String class provides an overloaded constructor for this.
String s = new String(byteArray, "UTF-8");
byteArray = s.getBytes("UTF-8");
Providing an explicit encoding charset is encouraged because different encoding schemes may have different byte representations. Read more here and here.
Also, your inputstream maynot read all the contents in one go. You have to read in a loop until there is nothing more left to be read. Read the documentation. read() returns the number of bytes read.
Reads up to b.length bytes of data from this input stream into an
array of bytes. This method blocks until some input is available
String.getBytes() and String(byte[] bytes) are methods to consider.
Convert byte array to String
String s = new String(bFile , "ISO-8859-1" );
Convert String to byte array
byte bArray[] =s.getBytes("ISO-8859-1");

String to byte and viceversa in java

I am converting a byte[] array to string . And then converting the string back to byte[] array. Then on checking if both the arrays are equal - I get that they are not equal:
byte[] ciphertext2=c.doFinal(username.getBytes("utf-8"));
//JUST CHECKING IGNORE
String qaz=new String(ciphertext2,"utf-8");
//qaz=qaz+"1";
System.out.println("just chekcing------------------------"+qaz);
byte[] ciphertext3=qaz.getBytes("utf-8");
if(Arrays.equals(ciphertext2,ciphertext3))
{
System.out.println("just chekcing they are equal------------------------");
}
else
System.out.println("just chekcing they are not equal------------------------");<br>
OUTPUT :
just chekcing they are not equal--------------------
Why doesn't it work?
Edit
It works perfectly fine when using Base64 of java. But why doesn't it work when converting byte to string and vice-versa directly? What actually happens when you convert a string a byte array and vice versa?
If this is the result of encryption, you should not be using a string constructor. You don't have encoded text - you have arbitrary binary data. You need to understand the difference between data which is fundamentally text and which needs to be represented in binary (e.g. writing a text file to disk) and data which is fundamentally binary and which needs to be represented in text (e.g. including encrypted data in an XML document).
You should use base64 (e.g. with this public domain library) or possibly hex. This will result in ASCII data which is guaranteed to roundtrip to the original binary data.

Java String to Byte Conversion [duplicate]

This question already has an answer here:
Closed 11 years ago.
Possible Duplicate:
Java AES Encrypt Entire String
Im having problems with the conversions back and forth between strings and byte arrays.
Basically I've made a small program to encrypt and decrypt messages using AES.
After encrypting the message this happens:
byte[] result = cipher.doFinal(message.getBytes());
String stringResult = new String(result);
Which converts the encrypted message to a string.
Now my decryptor changes the string back to a byte using:
byte[] result = stringResult.getBytes();
but when it decrypts the message (depending on the message) it may not be able to. There appears to be a padding problem and the error that I get is:
Exception in thread "main" javax.crypto.BadPaddingException: Given final block not properly padded
Any ideas why this occurs?
One example when this occurs for sure is when the encryption key is "1231231231231231" and the message encrypted is "read".
You're using the platform default encoding - once to convert message to bytes, and once to then convert the arbitrary binary output of encryption back into a string. Both steps are problematic.
Firstly, it's best to use a fixed encoding which is known to cover the whole of Unicode when converting the string to bytes. UTF-8 is usually a good bet.
Then there's the matter of representing arbitrary binary data as text. This isn't text data represented in an encoding - it's binary data. Interpreting it as if it were text data will almost certainly lose information. You need something more robust, capable of round-tripping arbitrary binary data. Base64 is usually the way to go.
There's a public domain base64 encoder which works pretty well as far as I know. So your encryption code becomes:
byte[] result = cipher.doFinal(message.getBytes("UTF-8"));
String stringResult = Base64.encodeBytes(result);
The decrypting code would then be:
byte[] encrypted = Base64.decode(encryptedBase64);
byte[] decrypted = /* do the decryption here */
String message = new String(decrypted, "UTF-8");
Your encrypted bytes are binary data which are unlikely to survive conversion to a string and back. If it needs to be stored in a string then Base64 encode it.

Categories