Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Base64: java.lang.IllegalArgumentException: Illegal character

I'm trying to send a confirmation email after user registration. I'm using the JavaMail library for this purpose and the Java 8 Base64 util class.

I'm encoding user emails in the following way:

byte[] encodedEmail = Base64.getUrlEncoder().encode(user.getEmail().getBytes(StandardCharsets.UTF_8)); Multipart multipart = new MimeMultipart(); InternetHeaders headers = new InternetHeaders(); headers.addHeader("Content-type", "text/html; charset=UTF-8"); String confirmLink = "Complete your registration by clicking on following"+ "\n<a href='" + confirmationURL + encodedEmail + "'>link</a>"; MimeBodyPart link = new MimeBodyPart(headers, confirmLink.getBytes("UTF-8")); multipart.addBodyPart(link); 

where confirmationURL is:

private final static String confirmationURL = "http://localhost:8080/project/controller?command=confirmRegistration&ID="; 

And then decoding this in ConfirmRegistrationCommand in such way:

    String encryptedEmail = request.getParameter("ID");      String decodedEmail = new String(Base64.getUrlDecoder().decode(encryptedEmail), StandardCharsets.UTF_8);      RepositoryFactory repositoryFactory = RepositoryFactory             .getFactoryByName(FactoryType.MYSQL_REPOSITORY_FACTORY);     UserRepository userRepository = repositoryFactory.getUserRepository();     User user = userRepository.find(decodedEmail);      if (user.getEmail().equals(decodedEmail)) {         user.setActiveStatus(true);         return Path.WELCOME_PAGE;     } else {         return Path.ERROR_PAGE;     } 

And when I'm trying to decode:

http://localhost:8080/project/controller?command=confirmRegistration&ID=[B@6499375d 

I'm getting java.lang.IllegalArgumentException: Illegal base64 character 5b.

I tried to use basic Encode/Decoder (not URL ones) with no success.

SOLVED:

The problem was the next - in the line:

 String confirmLink = "Complete your registration by clicking on following"+ "\n<a href='" + confirmationURL + encodedEmail + "'>link</a>"; 

I'm calling toString on an array of bytes, so I should do the following:

String encodedEmail = new String(Base64.getEncoder().encode(                 user.getEmail().getBytes(StandardCharsets.UTF_8))); 

Thanks to Jon Skeet and ByteHamster.

like image 690
marknorkin Avatar asked Feb 18 '15 12:02

marknorkin


People also ask

What are illegal Base64 characters?

As a result, the Transform Message component was returning this error: “Illegal base64 character 5f". This error happens when the string that you are trying to transform contains a character not recognized by the basic Base 64 Alphabet (in this case it was an underscore character).

Can Base64 contain slashes?

No. The Base64 alphabet includes A-Z, a-z, 0-9 and + and / . You can replace them if you don't care about portability towards other applications.

How does a Base64 string look like?

Base-64 maps 3 bytes (8 x 3 = 24 bits) in 4 characters that span 6-bits (6 x 4 = 24 bits). The result looks something like "TWFuIGlzIGRpc3Rpb...".

What is base 64 format?

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.


2 Answers

Your encoded text is [B@6499375d. That is not Base64, something went wrong while encoding. That decoding code looks good.

Use this code to convert the byte[] to a String before adding it to the URL:

String encodedEmailString = new String(encodedEmail, "UTF-8"); // ... String confirmLink = "Complete your registration by clicking on following"     + "\n<a href='" + confirmationURL + encodedEmailString + "'>link</a>"; 
like image 71
ByteHamster Avatar answered Oct 05 '22 18:10

ByteHamster


I encountered this error since my encoded image started with data:image/png;base64,iVBORw0....

This answer led me to the solution:

String partSeparator = ","; if (data.contains(partSeparator)) {   String encodedImg = data.split(partSeparator)[1];   byte[] decodedImg = Base64.getDecoder().decode(encodedImg.getBytes(StandardCharsets.UTF_8));   Path destinationFile = Paths.get("/path/to/imageDir", "myImage.png");   Files.write(destinationFile, decodedImg); } 

That code removes the meta data in front of the Base64-encoded image and passes the Base64 string to Java's Base64.Decoder to get the image as bytes.

like image 22
Matthias Braun Avatar answered Oct 05 '22 20:10

Matthias Braun