MethodInvocationException: Exception calling “FromBase64String” with “1” argument(s): “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.”

Well, what do you know – my 1000th post! 🥳 This blog turns 10 years next month, whoo hoo!

We use SecureAuth at work. And a bunch of users from some of our European and Asian offices complain that they get an error like this occassionally:

Digging further into this 1) it seems to be a known SecureAuth issue wherein it doesn’t like non-ASCII characters in names and but 2) it only affects some users with non-ASCII characters in their name (e.g. Chinese names or Umlauts and such) but not everyone with such characters.

Moreover, even amongst the users who are affected they are only affected when visiting some realms, not all.

I confirmed that yes it only seems to be some characters. If I create a test account and add any random Chinese character it doesn’t fail. Specific names seem to trigger this issue, and removing these names from the affected users fixes it for them too.

I wasn’t sure why it was only affecting some realms though. And why was the name coming into play? Everything was setup to use UPN or First Name and Last Name, and we didn’t really care about the Display Name. (Oh, that’s another thing – the Display Name was what mattered; if I added special characters in the Name that didn’t have an impact).

Digging even further into this I realized the issue affects our Azure AD realms. This was also obvious from the error message in retrospect. It talks about Conditional Access.

We have Azure AD setup to use SecureAuth for 2FA via a Custom Control. So a user authenticates against Azure AD, it sends the user to SecureAuth with some claims, and ideally SecureAuth should perform 2FA and pass the user on – but it wasn’t. I fired up SAML Tracer and checked what Azure AD was sending SecureAuth. I saw that it does a POST to SecureAuth with the id_token.

Interesting. So that explains the Base64 bit. This token is 3 Base64 segments after all (header, body, and signature) (I go into this in some detail in an earlier post) so what SecureAuth (or any other receiving platform) does is split this up along the dots and convert each to Base64.

If I put the above id_token into a site like jwt.ms I can see that it has the name with Chinese characters. So that explains how it is coming into play, even though we are not using it anywhere.

If I use PowerShell and split the token along the dot and try to decode the middle one, it too complains.

Same error as SecureAuth. And is what is expected according to the .NET docs for FromBase64String too.

If I put this Base64 blob into an online decoder site too (e.g. https://www.base64decoder.io/) it complains. So it sounds like some special characters when encoded into Base64 by Azure AD don’t result in valid Base64. The jwt.ms website probably fixes whatever is wrong intrinsically, but PowerShell and SecureAuth etc. don’t do that.

Reading up on how SecureAuth does its part I learnt that it has a VB file per realm (called “MSConditionalAccess.aspx.vb”) that has some code like this:

This is what does the actual conversion from Base64 to a string – the equivalent of what I did above in PowerShell. Notice it does one fix – replace any spaces with plus signs.

Googling confirmed the same, and looking more at the problem Base64 text I realized that it has dashes – and those definitely are not allowed. So I figured why not replace the dashes with pluses as above. Going back to PowerShell, that’s like doing:

And that actually works! I could get a stream of bytes.

I then tried converting these to text as I usually do:

But that gave some gibberish output:

Hmm. Wasn’t what I was expecting. If I were to put the fixed Base64 text (the one with dashes replaced with pluses) into the online decoder though, it works fine. So I am definitely on the right track!

Then I realized the gibberish is probably just encoding. I was doing Unicode above, should try something else too obviously. I thought Unicode was the same as UTF-8 (maybe it is?) but I tried using UTF-8 encoding too just in case.

And… that worked!

So it sounds like the fix then is to modify the VB function in SecureAuth to do a similar replace:

I didn’t, of course, try this as it’s a production system and I don’t know VB enough to be confident that this is all there is to it. So in that way this blog post is a bit of a downer with no happy ending, but I am pretty pleased I figured this out and I wanted to post about it. This investigation answered a bunch of questions for me, and that’s what counts! 🙂

On that note, here’s to 1000 more blog posts…

Update: The “Unicode” encoding class is actually UTF-16. So that’s why I got gibberish. The source text must have been encoded in UTF-8 by Azure AD, so showing it with the wrong encoding will obviously not work. Thanks to.