Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Decoding and Encoding issue. Different implementations of Base64 Class in android.util.* and java.util.*?

I am writing an App which does the following with a given String str:

encode(encrypt(encode(stringToBytearray(str))));

The Server receives the Base64 encoded String, which is then decoded -> decrypted -> decoded, to get the sent String str from the App.

Unfortunately it doesnt work for all Strings, long Strings lead to a long Base64 String and my Server throws the following Exception:

Exception in thread "main" java.lang.IllegalArgumentException: Illegal base64 character 5b
 at java.util.Base64$Decoder.decode0(Base64.java:714)
 at java.util.Base64$Decoder.decode(Base64.java:526)
 at Main.decode(Main.java:113)
 at Main.main(ain.java:33)

The String has the format "[string, string, ..., string]" without "s.

Like I mentioned above, for Strings which are not too long (sorry I cant quantify the length yet), this works. So I think I implemented it right.

Whats weird is, that if I dont send it, but decode(decrypt(decode(stringToBytearray(str)))); the String on the Device itself, it all works perfectly.

My Setup: JDK 7, eclipse (adt-bundle, android development) (Windows 7)

JDK 8, eclipse ('normal' java) (Linux (xubuntu))

Is it because both Classes (Base64) are implemented diffrently? If so, how can I make it work?

Here are the Encoding/Decoding Methods:

Encoding (Device: on Windows 7, adt-bundle, Android-Dev, jdk 7):

import android.util.Base64

public byte[] encode(byte[] bytearrayToEncode){
   return Base64.encode(bytearrayToEncode, Base64.NO_WRAP|Base64.URL_SAFE);
}

Decoding (Server: on Linux, jdk 8):

import java.util.Base64

public byte[] decode(byte[] bytearrayToEncode){
   return Base64.getUrlDecoder().decode(bytearrayToDecode);
}

Strings are all De-/Encoded with the same charset (utf-8)! Encoding/Decoding: Base64

Crypto: AES

If you need more Information, just ask, but I think I provided all neccessary informations.

Edit:

public String bytearrayToString(byte[] bytearray){
    String str = null;
    try {
        str = new String(bytearray, "UTF-8");
    } catch (UnsupportedEncodingException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    return str;
}

public byte[] stringToBytearray(String str){
    byte[] bytearray = null;
    try {
        bytearray = str.getBytes("UTF-8");
    } catch (UnsupportedEncodingException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    return bytearray;
}
like image 540
user3469811 Avatar asked Mar 27 '14 18:03

user3469811


People also ask

What is Base64 encoding and decoding in Java?

(Base 64 format reference). The Basic encoding means no line feeds are added to the output and the output is mapped to a set of characters in A-Za-z0-9+/ character set and the decoder rejects any character outside of this set. Encode simple String into Basic Base 64 format. String BasicBase64format= Base64.

What is Base64 encoding and decoding?

Base64 is a group of similar binary-to-text encoding schemes that represent binary data in an ASCII string format by translating it into a radix-64 representation. The term Base64 originates from a specific MIME content transfer encoding.

How do you check whether a string is Base64 encoded or not in Java?

As of Java 8, you can simply use java. util. Base64 to try and decode the string: String someString = "..."; Base64.


2 Answers

You must be using JSONObjects to send the Base64 String to the server. If so then the JSONObject will add " \ " escape characters to the string which are illegal Base64 characters. All you need to do is

String rectifiedString = Base64String.replace("\\","");

on the server end before using the acquired string.

Optional

Also on the server side use

import javax.xml.bind.DatatypeConverter;

and

String result = DatatypeConverter.printBase64Binary(bytearrayToDecode);

byte[] result = DatatypeConverter.parseBase64Binary(str);

instead.

It will not only get the job done but is much faster at encoding/decoding (as benchmarked here).

like image 166
Mohsin Ali Avatar answered Sep 19 '22 09:09

Mohsin Ali


If you have a space in your encoded string, which is an illegal character in base64. If you remove it, it still generates the same image/data in the converter you linked to, and can be now decoded by your code as well.

UPDATE: Some decoders (like the one you linked, or Base64.getMimeDecoder() in Java) ignore illegal characters, others (like Base64.getDecoder()) don't allow them.

like image 26
Anand Varkey Philips Avatar answered Sep 20 '22 09:09

Anand Varkey Philips