-
Notifications
You must be signed in to change notification settings - Fork 4.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
URL and filename safe base64 encoding #31099
Comments
FWIW, the X.509 OCSP isn't "encode base64url", it's "urlencode base64", per https://tools.ietf.org/html/rfc6960#appendix-A. |
@dotnet/ncl |
ASP.NET already has this implemented, so the question to me is how much value does this bring to non-ASP.NET apps? |
If this should go into .NET these apis should be added to Side note to
Disclaimer: I'm the author of https://github.com/gfoidl/Base64, which allows base64Url encoding / decoding (in the meaning of ASP.NET Core's usage) in a direct way (and not via replacements). |
I don't have numbers but here are some supporting points:
+1. I did not knew about this new |
Aside:
It got added in .NET Core 2.1. |
maybe base62 is a better solution. |
@maryamariyan @joperezr Any updates? Do you need help or something? |
I'm no longer the owner of this area. ping @dotnet/area-system-runtime, any updates here? |
I expect this one should actually be owned and driven by the networking team since it impacts
|
@MihaZupan any thoughts? |
@galakt what is your use case for this encoding? Are you using ASP.NET and the existing From a networking perspective, I can say that this kind of encoding looks useful (even if no protocol that the runtime itself currently implements uses it). The main rationale given for adding it is performance, but the most performant helpers ( As Jeremy points out, the proposal as currently written is confusing "base64url" with "url-encoded base64". These are two different encodings and these helpers shouldn't attempt to accommodate both.
Does any language that added such helpers produce anything but the first (and recommended) form? |
@MihaZupan We are working heavily with web tokens. We do not use base64Url directly, but via methods based on https://github.com/AzureAD/azure-activedirectory-identitymodel-extensions-for-dotnet/blob/dev/src/Microsoft.IdentityModel.Tokens/Base64UrlEncoder.cs I am not voting for this particular proposal, but just curious do you want to introduce base64Url encoding\decoding for parity with classic base64. Tricky question because there is already implemented WebEncoders. |
@galakt have you considered using the NuGet package mentioned above if the performance is important in your scenario? Unless we see more general interest in these APIs, I don't think we should be implementing them in core libraries, given that high-perf scenarios are already supported by the ecosystem (thanks @gfoidl!). |
Summary
The requirement of URL and filename safe alphabets in base64 strings is common in many applications that deal with resources over the network, not limited to web applications. Existing base64 encoding APIs do not provide option to encode in safe alphabets, forcing consumer to manually replace characters before and after the decoding and encoding operations respectively. Therefore, extending the existing base64 encoding API set in
System.Convert
to support safe alphabets would be quite useful in terms of completeness.Rationale and Usage
In order to achieve Base64Url encoding, one of the common technique is to call
System.Convert.ToBase64String
on the input, then truncate (or percentage-encode) the trailing=
characters, and finally replace+
characters with-
and/
with_
. For example, the JSON Web Signature (JWS) RFC 7571 gives a C# example with similar code. This approach is also suggested in the top answer on SO. However, this approach is rendered inefficient under a high load, when compared to the spanified implementation internally used inOpenSslX509ChainProcessor
: https://github.com/dotnet/corefx/blob/e70e76159b3f34e4e35d241daf39d4f57f4bd82c/src/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Unix/OpenSslX509ChainProcessor.cs#L544or in WebEncoders from AspNetCore: https://github.com/aspnet/AspNetCore/blob/fd060ce8c36ffe195b9e9a69a1bbd8fb53cc6d7c/src/Shared/WebEncoders/WebEncoders.cs#L347
A unified efficient implementation, that conforms with RFC 4648 - Section 5 would prevent consumers from looking for it elsewhere. For reference, this API was included in Java 8 (in 2014).
Proposed API
Details
*Base64Url*
names is because RFC 4648 explicitly calls it out.Base64Url
encoded string is not a valid base64 string due to non-base64 (-
,_
and%
) characters.UrlAndPathSafeAlphabets = 2,
could had been considered inenum Base64FormattingOptions
for existing{To,From}Base64{CharArray,String}
APIs.ToBase64Url..
methods are conformant to RFC 4648. If the input length is known (which is the case here) and there is a pad characters=
, it will be truncated (as opposed to percentage encoded).FromBase64Url..
methods accept all cases of RFC 4648 and two non-RFC ones,%2B
and%2F
mentioned in the case below:OpenSslX509ChainProcessor.Base64UrlEncode
is not conforming to RFC as it percentage-encodes+
(%2B
) and/
(%2F
) characters, whereas RFC only calls out pad character=
to be optionally percentage-encoded and which can be dropped if length is known.WebEncoders.Base64UrlDecode
is also not conforming to RFC 4648. For example, the inputTestString
can be encoded as any of the following, butBase64UrlDecode
only recognizes first two and throwsFormatException
for the third:VGVzdFN0cmluZw
VGVzdFN0cmluZw==
VGVzdFN0cmluZw%3D%3D
Open Questions
Are there cases where consumer explicitly do not want to omit the pad character and expect the API to percentage-encode it? For example, going by the usage of
OpenSslX509ChainProcessor.Base64UrlEncode
, it is not clear whether it will break something if this method simply omits=
and replace+
and/
with-
and_
respectively.The text was updated successfully, but these errors were encountered: