问题
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;
}
回答1:
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).
回答2:
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.
回答3:
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");
来源:https://stackoverflow.com/questions/22696126/decoding-and-encoding-issue-different-implementations-of-base64-class-in-androi