2017-01-16 58 views
0

我正在創建一個可以生成JWT令牌的方法。部分方法從我的web.config中讀取一個值,該值用作生成用於爲JWT令牌創建簽名的哈希的「祕密」。TextEncodings.Base64Url.Decode vs Convert.FromBase64String

<add key="MySecret" value="j39djak49H893hsk297353jG73gs72HJ3tdM37Vk397" /> 

最初我嘗試使用以下方法將「祕密」值轉換爲字節數組。

byte[] key = Convert.FromBase64String(ConfigurationManager.AppSettings["MySecret"]); 

然而,當該線達到引發了異常...

輸入不是有效的Base-64字符串,因爲它含有非基本64字符,兩個以上的填充字符或填充字符中的非法字符。

所以我看着OAuth的代碼,因此在使用另一種方法來改變一個base64字符串轉換爲字節數組

byte[] key = TextEncodings.Base64Url.Decode(ConfigurationManager.AppSettings["MySecret"]); 

這種方法的工作沒有問題。對我來說,看起來他們正在做同樣的事情。將Base64文本值更改爲字節數組。但是,我必須錯過一些東西。爲什麼Convert.FromBase64String失敗並且TextEncodings.Base64Url.Decode有效?

回答

1

當我將身份驗證服務遷移到.NET Core時,我遇到了同樣的情況。我查看了我們之前實現中使用的庫的源代碼,實際上名稱本身不同。

TextEncodings類有兩種類型的文本編碼器,Base64TextEncoder和Base64UrlEncoder。後者稍微修改了字符串,以便base64字符串可以在url中使用。

我的理解是,它是quite common用+和/替換 - 和_。事實上,我們一直在使用我們的握手令牌。此外,最後的填充字符也可以被刪除。這給我們留下了以下實現(this is from the source code):

public class Base64UrlTextEncoder : ITextEncoder 
{ 
    public string Encode(byte[] data) 
    { 
     if (data == null) 
     { 
      throw new ArgumentNullException("data"); 
     } 

     return Convert.ToBase64String(data).TrimEnd('=').Replace('+', '-').Replace('/', '_'); 
    } 

    public byte[] Decode(string text) 
    { 
     if (text == null) 
     { 
      throw new ArgumentNullException("text"); 
     } 

     return Convert.FromBase64String(Pad(text.Replace('-', '+').Replace('_', '/'))); 
    } 

    private static string Pad(string text) 
    { 
     var padding = 3 - ((text.Length + 3) % 4); 
     if (padding == 0) 
     { 
      return text; 
     } 
     return text + new string('=', padding); 
    } 
} 
相關問題