Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

base64.decode: Invalid encoding before padding

I'm working on a flutter project and I'm currently getting an error with some of the strings I try do decode using the base64.decode() method. I've created a short dart code which can reproduce the problem I'm facing with a specific string:

import 'dart:convert';

void main() {
  final message = 'RU5UUkVHQUdSQVRJU1==';
  print(utf8.decode(base64.decode(message)));
}

I'm getting the following error message:

Uncaught Error: FormatException: Invalid encoding before padding (at character 19)
RU5UUkVHQUdSQVRJU1==

I've tried decoding the same string with JavaScript and it works fine. Would be glad if someone could explain why am I getting this error, and possibly show me a solution. Thanks.

like image 972
Gabriel Kojima Avatar asked Sep 05 '25 03:09

Gabriel Kojima


1 Answers

Use Underline character "_" as Padding Character and Decode With Pad Bytes Deleted

For some reason dart:convert's base64.decode chokes on strings padded with = with the "invalid encoding before padding error". This happens even if you use the package's own padding method base64.normalize which pads the string with the correct padding character =.

= is indeed the correct padding character for base64 encoding. It is used to fill out base64 strings when fewer than 24 bits are available in the input group. See RFC 4648, Section 4.

However, RFC 4648 Section 5 which is a base64 encoding scheme for Urls uses the underline character _ as padding instead of = to be Url safe.

Using _ as the padding character will cause base64.decode to decode without error.

In order to further decode the generated list of bytes to Utf8, you will need to delete the padding bytes or you will get an "Invalid UTF-8 byte" error.

See the code below. Here is the same code as a working dartpad.dev example.

    import 'dart:convert';

void main() {
  //String message = 'RU5UUkVHQUdSQVRJU1=='; //as of dart 2.18.2 this will generate an "invalid encoding before padding" error
  //String message = base64.normalize('RU5UUkVHQUdSQVRJU1'); // will also generate same error

  String message = 'RU5UUkVHQUdSQVRJU1';
  print("Encoded String: $message");
  print("Decoded String: ${decodeB64ToUtf8(message)}");
}

decodeB64ToUtf8(String message) {
  message =
      padBase64(message); // pad with underline => ('RU5UUkVHQUdSQVRJU1__')
  List<int> dec = base64.decode(message);
  //remove padding bytes
  dec = dec.sublist(0, dec.length - RegExp(r'_').allMatches(message).length);
  return utf8.decode(dec);
}

String padBase64(String rawBase64) {
  return (rawBase64.length % 4 > 0)
      ? rawBase64 += List.filled(4 - (rawBase64.length % 4), "_").join("")
      : rawBase64;
}


like image 114
CoderBlue Avatar answered Sep 07 '25 21:09

CoderBlue