Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

TextEncodings.Base64Url.Decode vs Convert.FromBase64String

I was working on creating a method that would generate a JWT token. Part of the method reads a value from my web.config that services as the "secret" used to generate the hash used to create the signature for the JWT token.

<add key="MySecret" value="j39djak49H893hsk297353jG73gs72HJ3tdM37Vk397" />

Initially I tried using the following to convert the "secret" value to a byte array.

byte[] key = Convert.FromBase64String(ConfigurationManager.AppSettings["MySecret"]);

However, an exception was thrown when this line was reached ...

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.

So I looked into the OAuth code and so another method being used to change a base64 string into a byte array

byte[] key = TextEncodings.Base64Url.Decode(ConfigurationManager.AppSettings["MySecret"]);

This method worked without issue. To me it looks like they are doing the same thing. Changing a Base64 text value into an array of bytes. However, I must be missing something. Why does Convert.FromBase64String fail and TextEncodings.Base64Url.Decode work?

like image 308
webworm Avatar asked Jan 16 '17 22:01

webworm


People also ask

What is convert FromBase64String?

Converts the specified string, which encodes binary data as base-64 digits, to an equivalent 8-bit unsigned integer array. public: static cli::array <System::Byte> ^ FromBase64String(System::String ^ s);

What is Base64URL decode?

Base64URL Decode is a free online tool for decoding Base64URL values to original data. By default, it decodes Base64URL as plain text, nevertheless, it also supports binary data, such as images or other files.

What is Base64URL format?

base64url.com 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. Each base64 digit represents exactly 6 bits of data. Design.

Can browser decode Base64?

Encoding and Decoding Strings with Base64 btoa() and atob() are two Base64 helper functions that are a core part of the HTML specification and available in all modern browsers.


1 Answers

I came across the same thing when I migrated our authentication service to .NET Core. I had a look at the source code for the libraries we used in our previous implementation, and the difference is actually in the name itself.

The TextEncodings class has two types of text encoders, Base64TextEncoder and Base64UrlEncoder. The latter one modifies the string slightly so the base64 string can be used in an url.

My understanding is that it is quite common to replace + and / with - and _. As a matter of fact we have been doing the same with our handshake tokens. Additionally the padding character(s) at the end can also be removed. This leaves us with the following implementation (this is from the source code):

public class Base64UrlTextEncoder : ITextEncoder
{
    public string Encode(byte[] data)
    {
        if (data == null)
        {
            throw new ArgumentNullException("data");
        }

        return Convert.ToBase64String(data).TrimEnd('=').Replace('+', '-').Replace('/', '_');
    }

    public byte[] Decode(string text)
    {
        if (text == null)
        {
            throw new ArgumentNullException("text");
        }

        return Convert.FromBase64String(Pad(text.Replace('-', '+').Replace('_', '/')));
    }

    private static string Pad(string text)
    {
        var padding = 3 - ((text.Length + 3) % 4);
        if (padding == 0)
        {
            return text;
        }
        return text + new string('=', padding);
    }
}
like image 135
Iris Classon Avatar answered Oct 10 '22 00:10

Iris Classon