How to securely encode Base64 URLs in C #?

I want to get a secure encoding of Base64 URL in C #. In Java, we have a common Codec library that gives me a string with secure URL encoding. How can I achieve the same using C #?

 byte[] toEncodeAsBytes = System.Text.ASCIIEncoding.ASCII.GetBytes("StringToEncode"); string returnValue = System.Convert.ToBase64String(toEncodeAsBytes); 

The above code converts it to Base64, but it pads == . Is there a way to provide secure URL encoding?

+82
c # encoding base64
Oct 14 '14 at 6:06
source share
7 answers

It is usually simple to replace the alphabet for use in URLs, so no% coding is required; only 3 out of 65 characters are problematic - + , / and = . the most common replacements are - instead of + and _ instead of / . As for the add-on: just delete it ( = ); You can specify the amount of filling required. At the other end: just change the process:

 string returnValue = System.Convert.ToBase64String(toEncodeAsBytes) .TrimEnd(padding).Replace('+', '-').Replace('/', '_'); 

from:

 static readonly char[] padding = { '=' }; 

and vice versa:

 string incoming = returnValue .Replace('_', '/').Replace('-', '+'); switch(returnValue.Length % 4) { case 2: incoming += "=="; break; case 3: incoming += "="; break; } byte[] bytes = Convert.FromBase64String(incoming); string originalText = Encoding.ASCII.GetString(bytes); 

An interesting question, however, is this: is the same approach used by the “common codec library”? Of course, it would be wise to check first - this is a fairly common approach.

+152
Oct. 14 '14 at 7:10
source share

You can use the Base64UrlEncoder class from the Microsoft.IdentityModel.Tokens namespace.

 const string StringToEncode = "He=llo+Wo/rld"; var encodedStr = Base64UrlEncoder.Encode(StringToEncode); var decodedStr = Base64UrlEncoder.Decode(encodedStr); if (decodedStr == StringToEncode) Console.WriteLine("It works!"); else Console.WriteLine("Dangit!"); 
+64
Sep 30 '16 at 12:29
source share

Based on the answers here with some performance improvements, we published a very easy-to-use safe base64 version for NuGet with source code available on GitHub (MIT license).

Use is as simple as

 var bytes = Encoding.UTF8.GetBytes("Foo"); var encoded = UrlBase64.Encode(bytes); var decoded = UrlBase64.Decode(encoded); 
+8
Jul 17 '17 at 18:28
source share

Use System.Web.HttpServerUtility.UrlTokenEncode (bytes) for encoding and System.Web.HttpServerUtility.UrlTokenDecode (bytes) for decoding.

+7
Oct 07 '15 at 17:47
source share

Another option, if you use ASP.NET Core, would be to use Microsoft.AspNetCore.WebUtilities.WebEncoders.Base64UrlEncode .

If you are not using the ASP.NET Kernel, the WebEncoders source is available under the Apache 2.0 License .

+7
Feb 19 '18 at 3:00
source share

Here's another way to decode a secure base64 url ​​was encoded in the same way with Marc. I just don't understand why 4-length%4 worked (it does).

As shown below, only the source bit length is a common multiple of 6 and 8, base64 does not add the result "=".

 1 2 3 4 5 6 7 8|1 2 3 4 5 6 7 8|1 2 3 4 5 6 7 8 1 2 3 4 5 6|1 2 3 4 5 6|1 2 3 4 5 6|1 2 3 4 5 6 "==" "=" 

So, we can do it the other way around, if the bit length of the result cannot be divided by 8, it was added:

 base64String = base64String.Replace("-", "+").Replace("_", "/"); var base64 = Encoding.ASCII.GetBytes(base64String); var padding = base64.Length * 3 % 4;//(base64.Length*6 % 8)/2 if (padding != 0) { base64String = base64String.PadRight(base64String.Length + padding, '='); } return Convert.FromBase64String(base64String); 
0
Jan 04 '15 at 11:00
source share

There are a lot of good answers here. Getting rid of +, / and = is simple enough for every line with String.Replace, but I usually have a helper class that removes special characters in most of my projects.

  public static class Helpers { public static string RemoveSpecialCharacters(string str) { return Regex.Replace(str, "[^a-zA-Z0-9]", "", RegexOptions.Compiled); } } 

I used this to help me create a token.

 using (RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider()) { byte[] data = new byte[ByteLength]; rng.GetBytes(data); return Helpers.RemoveSpecialCharacters(Convert.ToBase64String(data)); } 
-one
May 03 '17 at 18:11
source share



All Articles