10

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;
}
4
  • 0x5b is [, and as I said the String format is [string, ..., string]. But why does all encoding/decoding work on the Device, but not on the Server, when the String is too long. (i compared both long strings, and they are equal) Commented Mar 27, 2014 at 18:41
  • Is your server trimming the query param when length is too large? Just try to echo the received base-64 message and check if they are exactly equal. Because truncated string may no longer be a valid Base-64 encrypted message. Commented Mar 27, 2014 at 19:12
  • I just found out, that the second call of encode, does not apply (even though i thought i have checked it). So far, thanks for all suggestions! I will try to figure out why it doesnt. Commented Mar 27, 2014 at 20:49
  • I have struggled a bit with the different encoders in java.util.Base64. Have you tried Base64.getDecoder() instead of Base64.getUrlDecoder()? Commented Apr 17, 2017 at 12:11

3 Answers 3

11

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).

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

1 Comment

Looks to me like printBase64Binary strips the backslash for you. Thanks for the insight. I had the same issue as OP.
1

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.

Comments

0

Use for encode:

Base64.getEncoder().encodeToString(yourString.getBytes("UTF-8"));

and decode:

byte[] decodedBytes = Base64.getDecoder().decode(yourString);
String stringDecode = new String(decodedBytes, "UTF-8");

Comments

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.