Come raggiungere la codifica sicura di Base64 URL in C #?

Voglio ottenere la codifica sicura di Base64 URL in C #. In Java, abbiamo la libreria Codec comune che mi dà una stringa codificata sicura per l’URL. Come posso ottenere lo stesso usando C #?

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

Il codice sopra lo converte in Base64, ma i pad == . C’è un modo per ottenere la codifica sicura dell’URL?

È normale scambiare semplicemente l’alfabeto per l’uso in urls, in modo che non sia necessaria la codifica%; solo 3 dei 65 caratteri sono problematici – + , / e = . le sostituzioni più comuni sono - al posto di + e _ al posto di / . Per quanto riguarda il padding: basta rimuoverlo (il = ); puoi dedurre la quantità di imbottitura necessaria. Dall’altra parte: basta invertire la procedura:

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

con:

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

e per invertire:

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

La domanda interessante, tuttavia, è la seguente: è lo stesso approccio utilizzato dalla “libreria di codec comune”? Sarebbe sicuramente una prima cosa ragionevole da testare: questo è un approccio abbastanza comune.

È ansible utilizzare la class Base64UrlEncoder dallo spazio dei nomi 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!"); 

Utilizzare System.Web.HttpServerUtility.UrlTokenEncode (byte) da codificare e System.Web.HttpServerUtility.UrlTokenDecode (byte) da decodificare.

Basandoci sulle risposte qui con alcuni miglioramenti delle prestazioni, abbiamo pubblicato un’implementazione base64 url-safe molto facile da usare in NuGet con il codice sorgente disponibile su GitHub (con licenza MIT).

L’utilizzo è facile come

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

Un’altra opzione, se si utilizza ASP.NET Core, sarebbe utilizzare Microsoft.AspNetCore.WebUtilities.WebEncoders.Base64UrlEncode .

Se non si utilizza ASP.NET Core, l’origine WebEncoders è disponibile con la licenza Apache 2.0 .

Ecco un altro metodo per decodificare un url-safe base64 è stato codificato nello stesso modo con Marc. Non capisco perché 4-length%4 funzionato (lo fa).

Come segue, solo la lunghezza del bit dell’origine sono multipli comuni di 6 e 8, base64 non aggiunge “=” al risultato.

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

Quindi possiamo farlo al contrario, se la lunghezza del bit del risultato non può essere divisibile per 8, è stato aggiunto:

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

Utilizzo del motore di crittografia Microsoft in UWP.

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