Как добиться безопасного кодирования URL Base64 в C#?


Я хочу добиться безопасного кодирования URL Base64 в C#. В Java, у нас есть общие Codec библиотека, которая дает мне безопасную кодированную строку URL. Как я могу добиться того же с помощью C#?

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

приведенный выше код преобразует его в base64, но это колодки ==. Есть ли способ добиться безопасного кодирования URL?

7 63

7 ответов:

обычно просто поменять алфавит для использования в URL-адресах, так что не требуется %-кодировка; только 3 из 65 символов являются проблематичными - +,/ и =. наиболее распространенными заменами являются - на месте + и _ на месте /. Что касается обивки:просто удалить это (the =); вы можете вывод необходимое количество прокладок. На другом конце: как раз обратный процесс:

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

С:

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

и обратное:

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);

интересный вопрос, однако, является: это тот же подход, который использует" общая библиотека кодеков"? это, безусловно, было бы разумным первым делом проверить - это довольно распространенный подход.

вы можете использовать класс Base64UrlEncoder из пространства имен Microsoft.IdentityModel.Tokens.

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!");

Системы Использовать.Сеть.HttpServerUtility.UrlTokenEncode (байты) для кодирования, и Система.Сеть.HttpServerUtility.UrlTokenDecode (байты) для декодирования.

основываясь на ответах здесь с некоторыми улучшениями производительности, мы опубликовали очень простой в использовании url-безопасная реализация base64 в NuGet исходный код доступно на GitHub (лицензия MIT).

использование так же просто, как

var bytes = Encoding.UTF8.GetBytes("Foo");
var encoded = UrlBase64.Encode(bytes);
var decoded = UrlBase64.Decode(encoded);

другой вариант, если вы используете ASP.NET ядро, было бы использовать Microsoft.AspNetCore.WebUtilities.WebEncoders.Base64UrlEncode.

Если вы не используете ASP.NET ядро,the WebEncoders источник под Лицензия Apache 2.0.

вот еще один способ для декодирования URL-адрес для просмотра в base64 закодировать был такой же как с Марком. Я просто не понимаю, почему 4-length%4 работали(он делает).

как следует, только длина бита источника являются общими кратными 6 и 8, base64 не добавляют " = " к результату.

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
                "=="            "="

поэтому мы можем сделать это наоборот, если длина бита результата не может делиться на 8, он был добавлен:

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);

использование Microsoft cryptographic engine в UWP.

uint length = 32;

IBuffer buffer = CryptographicBuffer.GenerateRandom(length);
string base64Str = CryptographicBuffer.EncodeToBase64String(buffer)
                   // ensure url safe
                   .TrimEnd('=').Replace('+', '-').Replace('/', '_');

return base64Str;