5

I am writing a function to manually verify and get the header and payload pairs of a jwt access_token i am testing with the sample token available at https://jwt.io/ My code is very simple at this point

string[] tokenSegments = Token.Split('.');
string tokenHeaders = Encoding.UTF8.GetString(Convert.FromBase64String(tokenSegments[0]));
string tokenPayload = Encoding.UTF8.GetString(Convert.FromBase64String(tokenSegments[1]));

when it reaches the tokenPayloadLine im getting the following exception

System.FormatException: The input is not a valid Base-64 string as it contains >a non-base 64 character, more than two padding characters, or an illegal >character among the padding characters. at System.Convert.FromBase64CharPtr(Char* inputPtr, Int32 inputLength) at System.Convert.FromBase64String(String s)

and the exception is being thrown at this level

Convert.FromBase64String(tokenSegments[1])

please note that i can get the header values without any exception

i have tried and edited the Token to change the integer value available at the payload to make it a string and then i was successful at getting the payload

just a comparison the encoded string that is throwing the exception is

eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ

and the one that is working fine is

eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoiMTUxNjIzOTAyMiJ9

if you decode both of them you can find that the only difference is the integer value causing the exception

am i doing something wrong? is this not an intended use for the Convert Function? any thought or suggestion would be helpful also please note that i need to do this manually as i am fully aware of the jwt libraries available online.

Wai Ha Lee
  • 8,598
  • 83
  • 57
  • 92
maces13
  • 305
  • 3
  • 13
  • 1
    I would have expected an invalid length exception, not this one. – bommelding Jan 16 '19 at 11:30
  • 4
    JWT doesn't use plain Base64, it uses something called [base64url encoding](https://brockallen.com/2014/10/17/base64url-encoding/). The `Convert` methods can't handle that (but the page I've linked to helpfully includes some code, and links to library methods). – Jeroen Mostert Jan 16 '19 at 11:39
  • Possible duplicate of [TextEncodings.Base64Url.Decode vs Convert.FromBase64String](https://stackoverflow.com/questions/41685931/textencodings-base64url-decode-vs-convert-frombase64string) – Jeroen Mostert Jan 16 '19 at 11:59

1 Answers1

17

Base64 needs padding with = at the end, not every tool adds those.

string  s = // some base64 witout padding;
s = s.PadRight(s.Length + (s.Length * 3) % 4, '=');  // add padding
var data = Convert.FromBase64String(s);
GTInsight
  • 68
  • 6
bommelding
  • 2,969
  • 9
  • 14
  • Thanks, this worked for me. Can anyone add some explanation to this answer? I don't fully understand what this is doing. – JakeD Jul 01 '22 at 15:38