Problem with Base64::convertFromBase64

Hi, I have a base 64 string (the payload from a JWT token) which looks like it should decode ok (i.e. works in https://www.base64decode.org/ )
but fails to decode with Base64::convertFromBase64 function. Failure happens while decoding the last character of the input string. here’s the code:

String jwtPayload = “eyJ0eXBlIjoiVVNFUiIsInR5cGVJZCI6IjgwZjk0OTdlLTFlYmQtNDFhNy1iOTg4LTcwZmQ5OGQ3MjBhZCIsInJvbGUiOiIxMTEwMTAwMDAxMSIsImV4cCI6MTU1Mzg3NzEyMSwiaWF0IjoxNTUzMjcyMzIxfQ”;
MemoryOutputStream decodedStream;

if (Base64::convertFromBase64 (decodedStream, jwtPayload)){
DBG("decode ok : payload = " << decodedStream.toString());
}
else {
DBG("decode ko : payload = " << decodedStream.toString());
}

Decode is ok up to the closing curly brace, i.e the output of this code is :

decode ko : payload = {“type”:“USER”,“typeId”:“80f9497e-1ebd-41a7-b988-70fd98d720ad”,“role”:“11101000011”,“exp”:1553877121,“iat”:1553272321

… which compared to the “working” base64 decoding misses only the last ‘}’

My suspects-coming-to-mind are:
#1) I’m doing something wrong with the input string (e.g. should add some terminating char or convert it to different encoding)
#2) I’m using badly the MemoryOutputStream
#3) the last field value not being a string but a number is causing trouble to the decoding algorithm

help…

I ran into this problem with JWT as well. Turns out the issue is a ‘not quite legal’ base64 string. ie. the string length is not a multiple of 4. I assume that all of the web tools that usual consume this data are more forgiving than the JUCE::Base64 class. My solution was to do this prior to converting it:

    payloadBase64 += String (std::string (payloadBase64.length() % 4, '='));
4 Likes

Whoa @cpr works like a charm and saves a friday night, kudos!

Glad my previous ‘friday night’ payed off for someone else… lol… :+1:

1 Like

I just made a feature request that the Base64 class be more forgiving in this manner. :slight_smile:

If anyone is looking for the Base64 encoding

I might be missing something, but shouldn’t this be:
payloadBase64 += String (std::string ((4 - payloadBase64.length() % 4) % 4, '='));

I believe you are correct. As I am a long time removed from the code that was using this, I have verified your assertion by just running tests on numbers representing lengths. I can’t verify why my original code worked on the project I was working on, or why it seemed to work for fefanto as well. Thanks for the update.

In this kind of situation I tend to favor simpler more straightforward solutions like

while (payloadBase64.length() % 4) {
    payloadBase64 += "=";
}