2014-10-14 23 views
55

Tôi muốn đạt được mã hóa an toàn của Base64 URL trong C#. Trong Java, chúng tôi có thư viện phổ biến là Codec mang đến cho tôi chuỗi được mã hóa an toàn bằng URL. Làm thế nào tôi có thể đạt được cùng một bằng cách sử dụng C#?Làm thế nào để đạt được mã hóa an toàn của Base64 URL trong C#?

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

Mã trên chuyển đổi nó thành Base64, nhưng nó được nhập ==. Có cách nào để đạt được mã hóa an toàn URL không?

+0

Bạn không thể sử dụng 'Url.Encode' trên chuỗi trong' BASE64'? –

+0

Trong đó lớp Url không gian tên có mặt trong C#? –

+0

Hãy xem: http://msdn.microsoft.com/en-us/library/system.web.httputility.urlencode%28v=vs.110%29.aspx Bạn cần tham khảo hội 'System.Web'. –

Trả lời

98

Phổ biến là chỉ cần hoán đổi bảng chữ cái để sử dụng trong url, do đó không cần mã hóa%; chỉ có 3 trong số 65 ký tự có vấn đề - +, /=. các thay thế phổ biến nhất là - thay cho +_ thay cho /. Đối với phần đệm: chỉ cần xóa nó (số =); bạn có thể suy ra số lượng đệm cần thiết. Ở đầu kia: chỉ cần đảo ngược quá trình:

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

với:

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

và để đảo ngược:

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

Câu hỏi thú vị, tuy nhiên, là: là này cùng cách tiếp cận mà "thư viện codec phổ biến" sử dụng? Nó chắc chắn sẽ là một điều đầu tiên hợp lý để kiểm tra - đây là một cách tiếp cận khá phổ biến.

+1

Trong Codec chung họ đang sử dụng [0-9a-zA-Z_-] Ký tự cho url chế độ an toàn. –

+0

điều này cũng được đề cập trong trang wiki cho Base64 trong các ứng dụng URL. http://en.wikipedia.org/wiki/Base64 – wonster

+1

Bạn cũng có chức năng này 'http://stackoverflow.com/questions/1886686/c-sharp-byte-to-url-friendly-string' thực hiện tất cả công việc khó khăn cho bạn. – toy4fun

0

Dưới đây là một phương pháp khác để giải mã base64 an toàn cho url được mã hóa theo cùng một cách với Marc. Tôi chỉ không hiểu tại sao 4-length%4 làm việc (nó).

Như sau, chỉ độ dài bit của nguồn gốc là bội số chung của 6 và 8, base64 không chắp thêm "=" vào kết quả.

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

Vì vậy, chúng ta có thể làm điều đó ngược lại, nếu chiều dài bit kết quả của không thể chia hết cho 8, nó đã được nối:

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

Sử dụng System.Web.HttpServerUtility.UrlTokenEncode (byte) để mã hóa và System.Web.HttpServerUtility.UrlTokenDecode (byte) để giải mã.

+3

Tính năng này không cung cấp mã hóa Base64 an toàn theo tiêu chuẩn tuân theo RFC4648. Xem thêm [câu hỏi này] (http://stackoverflow.com/questions/26732145/c-base64url-according-to-rfc4648). ** Sử dụng thận trọng. ** –

27

Bạn có thể sử dụng lớp Base64UrlEncoder từ không gian tên 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!"); 
+0

Điều này sạch hơn nhiều so với câu trả lời được chấp nhận. Bất kỳ nhược điểm nào? – taktak004

+3

Chỉ cần lưu ý: Microsoft.IdentityModel.Tokens là gói NuGet cần tải xuống. –

-1

Rất nhiều câu trả lời hay tại đây. Loại bỏ các +,/và = là đủ dễ dàng trên mỗi chuỗi với String.Replace nhưng tôi thường có một lớp trợ giúp loại bỏ các ký tự đặc biệt trong hầu hết các dự án của tôi.

public static class Helpers 
    { 
     public static string RemoveSpecialCharacters(string str) 
     { 
      return Regex.Replace(str, "[^a-zA-Z0-9]", "", RegexOptions.Compiled); 
     } 
    } 

Tôi sử dụng này để giúp tôi tạo ra một mã thông báo.

using (RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider()) 
      { 
       byte[] data = new byte[ByteLength]; 
       rng.GetBytes(data); 
       return Helpers.RemoveSpecialCharacters(Convert.ToBase64String(data)); 
      } 
+0

Nếu bạn chỉ tách một số ký tự, một số dữ liệu sẽ bị mất và chuỗi không còn có thể được giải mã – samfromlv

2

Dựa tắt các câu trả lời ở đây với một số cải tiến hiệu suất, chúng tôi đã công bố một rất dễ sử dụng url-safe base64 implementation to NuGet với mã nguồn available on GitHub (MIT cấp phép).

Cách sử dụng dễ dàng như

var bytes = Encoding.UTF8.GetBytes("Foo"); 
var encoded = UrlBase64.Encode(bytes); 
var decoded = UrlBase64.Decode(encoded); 
Các vấn đề liên quan