如何在 C# 中实现 Base64 URL 安全编码?

     2023-03-10     53

关键词:

【中文标题】如何在 C# 中实现 Base64 URL 安全编码?【英文标题】:How to achieve Base64 URL safe encoding in C#? 【发布时间】:2014-12-08 19:52:09 【问题描述】:

我想在 C# 中实现 Base64 URL 安全编码。在 Java 中,我们有一个通用的 Codec 库,它为我提供了一个 URL 安全编码字符串。如何使用 C# 实现相同的目标?

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

上面的代码将其转换为 Base64,但它填充了==。有没有办法实现 URL 安全编码?

【问题讨论】:

你不能在BASE64中的字符串上使用Url.Encode吗? c#中哪个命名空间Url类存在? 看一下:msdn.microsoft.com/en-us/library/…你需要引用System.Web组件。 它正在将 = 转换为 %3D。我不想要那个。 那么url safe 是什么意思? %3D 是网址安全的。 【参考方案1】:

在 url 中使用 简单地交换字母 是很常见的,因此不需要 % 编码; 65 个字符中只有 3 个有问题 - +/=。最常见的替换是- 代替+_ 代替/。至于填充:删除它=);您可以推断所需的填充量。在另一端:只需反转过程:

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

然而,有趣的问题是:这与“通用编解码器库”使用的方法相同吗?首先要进行测试肯定是合理的——这是一种非常常见的方法。

【讨论】:

在通用编解码器中,他们使用 [0-9a-zA-Z_-] 字符作为 url 安全模式。 这在 wiki page for Base64 的 URL applications 下也有提及。 en.wikipedia.org/wiki/Base64 你也有这个功能 '***.com/questions/1886686/…' 为你做所有的辛苦工作。 为什么我们不需要:案例1:传入+=“===”;休息; ? @alexdafranca 因为它永远不会有 1 的长度 mod 4。3x8 位变成 4x6 位(每 6 位是所选字母表中 64 个字符之一),0x8 位被编码为 0x6 位没有填充,1x8 位被编码为带有== 填充的 2x6 位,2x8 被编码为带有= 填充的 3x6,3x8 被编码为没有填充的 4x6,然后它被对齐以便重复。没有任何东西被编码为 1x6 位,因此您永远不需要 === 填充。【参考方案2】:

您可以使用命名空间 Microsoft.IdentityModel.Tokens 中的类 Base64UrlEncoder

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

【讨论】:

这比公认的答案要干净得多。有什么缺点吗? 请注意:Microsoft.IdentityModel.Tokens 是一个必须下载的 NuGet 包。 我假设这不是跨平台的。是这样吗?【参考方案3】:

如果您使用的是 ASP.NET Core,另一种选择是使用 Microsoft.AspNetCore.WebUtilities.WebEncoders.Base64UrlEncode

如果您未使用 ASP.NET Core,the WebEncoders source 可在 Apache 2.0 License 下使用。

【讨论】:

【参考方案4】:

根据此处的答案以及一些性能改进,我们发布了一个非常易于使用的url-safe base64 implementation to NuGet,其源代码为available on GitHub(MIT 许可)。

使用很简单

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

【讨论】:

非常感谢。出于兴趣,您为什么选择 "string".Replace 来代替 encode 方法,但使用手动替换 decode 的循环? 另一个返回类型 = 字符串的类:github.com/vndevpro/architecture-common/blob/master/…【参考方案5】:

要根据 RFC4648 获得 URL 安全的类似 base64 的编码,但不是“base64url”,请使用 System.Web.HttpServerUtility.UrlTokenEncode(bytes) 进行编码,并且 System.Web.HttpServerUtility.UrlTokenDecode(bytes) 解码。

【讨论】:

这不提供符合 RFC4648 标准的 URL 安全 Base64 编码。另见this Q&A。 谨慎使用。【参考方案6】:

最简单的解决方案: (没有填充)

private static string Base64UrlEncode(string input) 
    var inputBytes = System.Text.Encoding.UTF8.GetBytes(input);
    // Special "url-safe" base64 encode.
    return Convert.ToBase64String(inputBytes)
      .Replace('+', '-') // replace URL unsafe characters with safe ones
      .Replace('/', '_') // replace URL unsafe characters with safe ones
      .Replace("=", ""); // no padding
  

归功于:Tholle

【讨论】:

【参考方案7】:
    public string Decode(string str)
    
       byte[] decbuff = Convert.FromBase64String(str.Replace(",", "=").Replace("-", "+").Replace("/", "_"));
       return System.Text.Encoding.UTF8.GetString(decbuff);
    
    
    public string Encode(string input)
    
        byte[] encbuff = Encoding.UTF8.GetBytes(input ?? "");
        return Convert.ToBase64String(encbuff).Replace("=", ",").Replace("+", "-").Replace("_", "/");
    

这是与 JavaScript 保持一致的方法!

【讨论】:

【参考方案8】:

这是另一种解码 url-safe base64 的方法,它与 Marc 以相同的方式编码。我只是不明白为什么4-length%4 有效(确实如此)。

如下,只有origin的位长是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);

【讨论】:

【参考方案9】:

在 UWP 中使用 Microsoft 加密引擎。

uint length = 32;

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

return base64Str;

【讨论】:

【参考方案10】:

Karanvir Kang 的回答很好,我投了赞成票。但是,它确实在字符串的末尾留下了一个奇数字符(表示删除的填充字符的数量)。这是我的解决方案。

var bytesToEncode = System.Text.Encoding.UTF8.GetBytes("StringToEncode"); 
var bytesEncodedPadded = HttpServerUtility.UrlTokenEncode(bytesToEncode);
var objectIdBase64 = bytesEncodedPadded.Substring(0, bytesEncodedPadded.Length - 1);

【讨论】:

如何通过c#生成安全的base64url字符串?(代码片段)

咨询区VishveshPhadnis:在C#中如何实现对URL进行安全的base64编码,在JAVA中我可以使用Codec类库来实现此功能,我目前是这么实现的。byte[] toEncodeAsBytes = System.Text.ASCIIEncoding.ASCII.GetBytes("StringToEncode");string returnVa... 查看详情

如何在delphi中实现对文件进行base64编码

delphi中有个EncdDecd类,这个是delphi自带的base64编码类,里面提供了编码和解码函数分别是:functionEncodeString(constInput:string):string;//编码functionDecodeString(constInput:string):string;//解码参考技术ABase64=Class(TObject)privateFOStream:TStream;FIStream:TStr... 查看详情

使用c#实现url安全的base62转码

Base62编码与Base64编码类似,都用于数据内容编码。Base64和Base62的目的在都在于将需要传输的内容进行编码,尤其是一些特殊字符(如不可见字符、传输时与协议头冲突的字符)。与Base64不同的是,Base62编码是... 查看详情

如何使用 c# 在 paypal 中实现 DoDirectPayment

】如何使用c#在paypal中实现DoDirectPayment【英文标题】:HowtoimplementDoDirectPaymentinpaypalusingc#【发布时间】:2013-02-1416:23:33【问题描述】:我是贝宝的新手。我想为我的网站实现直接支付api。意味着当我点击它时我会有一个购买按钮... 查看详情

如何在delphi中实现对文件进行base64编码

参考技术A在delphi中,实现对文件进行base64编码,步骤如下:1、下载CnPack组件包(CnVCL)CnVCL是一个涵盖不可视工具组件、界面控件、网络通讯组件、多语言处理等多个方面的Delphi/C++Builder组件包2、将下载的zip解压到文件夹,再如... 查看详情

我一般如何在 MapRoute 方法中实现 URL 重写?

】我一般如何在MapRoute方法中实现URL重写?【英文标题】:HowdoIgenericallyimplementURL-rewritinginaMapRoutemethod?【发布时间】:2014-01-0605:57:59【问题描述】:我正在尝试将URL从C#的Pascal-case重写为对SEO友好的格式。例如,我希望像/User/Home/M... 查看详情

base64加密

...实现记住密码的效果,这是一种可逆的加密方式。  C#中实现Base64加密、解密代码如下:publicclassBase64{///< 查看详情

如何在内联汇编中实现这一点?

】如何在内联汇编中实现这一点?【英文标题】:Howtoimplementthisininlineassembly?【发布时间】:2014-06-0302:45:23【问题描述】:我在理解GNU内联汇编语法方面非常糟糕,所以我希望一个实际的例子能有所帮助。鉴于以下程序集(x86-64... 查看详情

如何将 Firebase 上传图片的图片下载 URL 转换为 base64

】如何将Firebase上传图片的图片下载URL转换为base64【英文标题】:HowtoconvertimagedownloadURLforFirebaseuploadimagetobase64【发布时间】:2019-12-2622:55:43【问题描述】:我正在尝试在Vue.jsFirebase应用程序中实现图像上传器组件。我将上传器设... 查看详情

如何在 C# 中实现 sdbm 哈希函数?

】如何在C#中实现sdbm哈希函数?【英文标题】:HowwouldasdbmhashfunctionbeimplementedinC#?【发布时间】:2010-09-0604:02:53【问题描述】:如何在C#中实现sdbm哈希函数(如this)?【问题讨论】:【参考方案1】:您几乎可以不加改动地获取C... 查看详情

如何在 C# 中实现 ORM

】如何在C#中实现ORM【英文标题】:HowtoimplementanORMinC#【发布时间】:2015-10-3018:34:15【问题描述】:我正在尝试在C#中为MySQL实现我自己的ORM,因为我发现它不能完全按照我的意愿去做。我目前只实现了几个方法(例如保存方法)... 查看详情

如何在c#中实现决策矩阵

】如何在c#中实现决策矩阵【英文标题】:Howtoimplementdecisionmatrixinc#【发布时间】:2013-05-2920:27:33【问题描述】:我需要根据一组相当大的8个相互依赖的条件做出决定。|A|B|C|D|E|F|G|H-----------+---+---+---+---+---+---+---+---Decision01|0|1|-|1|0... 查看详情

js中实现base64加密解密

//1.加密解密方法使用://1.加密varstr=‘124中文内容‘;varbase=newBase64();varresult=base.encode(str);//document.write(result);//2.解密varresult2=base.decode(result);document.write(result2);//2.加密、解密算法封装:functionBase64(){ 查看详情

如何在 C# 中实现单例设计模式? [复制]

】如何在C#中实现单例设计模式?[复制]【英文标题】:HowtoimplementsingletondesignpatterninC#?[duplicate]【发布时间】:2014-06-2800:20:24【问题描述】:如何在C#中实现单例设计模式?谁能帮帮我?【问题讨论】:如果你真的需要,请参阅cs... 查看详情

如何在 C# 中实现线程关联?

】如何在C#中实现线程关联?【英文标题】:HowdoIimplementthreadaffinityinC#?【发布时间】:2017-12-1422:09:33【问题描述】:我有一个需要线程关联的第三方API。我在我的服务应用程序中使用WCF来处理来自客户端的请求,然后将这些请求... 查看详情

如何在 C# 中实现 3 层架构

】如何在C#中实现3层架构【英文标题】:Howtoimplement3tiersarchitectureinc#【发布时间】:2012-11-2700:23:28【问题描述】:我阅读了很多关于c#中的3层架构的文章,但我看到了:几乎使用业务逻辑层(BLL)作为对象映射数据库中的对应表... 查看详情

如何在 C# 中实现 glob

】如何在C#中实现glob【英文标题】:HowtoimplementglobinC#【发布时间】:2010-09-2818:00:50【问题描述】:我不知道在***上发布您自己的问题答案是否合法,但我看到没有人问过这个问题。我去找了一个C#Glob,但没有找到,所以我写了... 查看详情

在 C# 中实现 runas

...runasinC#【发布时间】:2012-10-0106:16:23【问题描述】:我该如何实施runas/noprofile/netonly/user:@使用C#。System.Diagnostics.ProcessStartInfo具有用户、域、密码、动词(我们可以在其中使用runas)等字段,但如何设置netonly。使用Cmd它不需要令... 查看详情