Я хочу получить безопасное кодирование URL-адреса Base64 на С#. В Java у нас есть общая библиотека Codec
, которая дает мне строку с безопасным кодированием URL. Как я могу добиться того же, используя С#?
byte[] toEncodeAsBytes = System.Text.ASCIIEncoding.ASCII.GetBytes("StringToEncode");
string returnValue = System.Convert.ToBase64String(toEncodeAsBytes);
Вышеприведенный код преобразует его в Base64, но он прокладывает ==
. Есть ли способ обеспечить безопасное кодирование URL?
Ответ 1
Обычно просто заменять алфавит для использования в URL-адресах, так что не требуется% -кодирования; проблематично только 3 из 65 символов - +
, /
и =
. наиболее распространенными заменами являются -
вместо +
и _
вместо /
. Что касается дополнения: просто удалите его (=
); вы можете указать количество требуемого заполнения. На другом конце: просто измените процесс:
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);
Интересный вопрос, однако, заключается в следующем: является ли тот же подход, который использует "общая библиотека кодеков"? Конечно, было бы разумно сначала проверить - это довольно распространенный подход.
Ответ 2
Вы можете использовать класс 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!");
Ответ 3
Основываясь на полученных здесь ответах с некоторыми улучшениями производительности, мы опубликовали очень простую в использовании реализацию url-safe base64 для NuGet с исходным кодом , доступным на GitHub (лицензия MIT).
Использование так же просто, как
var bytes = Encoding.UTF8.GetBytes("Foo");
var encoded = UrlBase64.Encode(bytes);
var decoded = UrlBase64.Decode(encoded);
Ответ 4
Чтобы получить URL-безопасную кодировку в стиле base64, но не "base64url" в соответствии с RFC4648, используйте System.Web.HttpServerUtility.UrlTokenEncode(bytes)
для кодирования и
System.Web.HttpServerUtility.UrlTokenDecode(bytes)
для декодирования.
Ответ 5
Другой вариант, если вы используете ASP.NET Core, это использовать Microsoft.AspNetCore.WebUtilities.WebEncoders.Base64UrlEncode
.
Если вы не используете ядро ASP.NET, источник WebEncoders
доступен под лицензией Apache 2.0.
Ответ 6
Вот еще один способ декодирования защищенного url base64 был закодирован таким же образом с Marc. Я просто не понимаю, почему 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);
Ответ 7
Использование криптографического движка Microsoft в UWP.
uint length = 32;
IBuffer buffer = CryptographicBuffer.GenerateRandom(length);
string base64Str = CryptographicBuffer.EncodeToBase64String(buffer)
// ensure url safe
.TrimEnd('=').Replace('+', '-').Replace('/', '_');
return base64Str;
Ответ 8
Здесь много хороших ответов. Избавление от +,/и = достаточно просто для каждой строки с String.Replace, но у меня обычно есть вспомогательный класс, который удаляет специальные символы в большинстве моих проектов.
public static class Helpers
{
public static string RemoveSpecialCharacters(string str)
{
return Regex.Replace(str, "[^a-zA-Z0-9]", "", RegexOptions.Compiled);
}
}
Я использовал это, чтобы помочь мне создать токен.
using (RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider())
{
byte[] data = new byte[ByteLength];
rng.GetBytes(data);
return Helpers.RemoveSpecialCharacters(Convert.ToBase64String(data));
}