変更されたbase64 URLをデコード/エンコードするためのコード
質問
base64でデータをエンコードしてURLに入れ、HttpHandler内でデコードします。
Base64エンコーディングにより、「/」文字が混乱することがわかりました。 UriTemplateマッチング。その後、「URLの変更されたBase64」という概念があることがわかりました。ウィキペディアから:
パディング「=」が使用されず、標準Base64の「+」および「/」文字がそれぞれ「-」および「_」に置き換えられるURLバリアント用の変更されたBase64が存在するため、URLを使用エンコーダー/デコーダーは不要になり、エンコードされた値の長さに影響を与えず、同じエンコードされたフォームをそのままリレーショナルデータベース、Webフォーム、および一般的なオブジェクト識別子で使用できるようにします。
.NETを使用して、現在のコードを、基本的なbase64エンコードおよびデコードから「修正されたURLのbase64」の使用に変更します。方法。誰かこれをやったことがありますか?
デコードするには、次のようなもので始まることがわかります:
string base64EncodedText = base64UrlEncodedText.Replace('-', '+').Replace('_', '/');
// Append '=' char(s) if necessary - how best to do this?
// My normal base64 decoding now uses encodedText
しかし、1つまたは2つの '='文字を最後に追加する必要がある可能性があります。これはもう少し複雑に見えます。
エンコードロジックはもう少しシンプルにする必要があります。
// Perform normal base64 encoding
byte[] encodedBytes = Encoding.UTF8.GetBytes(unencodedText);
string base64EncodedText = Convert.ToBase64String(encodedBytes);
// Apply URL variant
string base64UrlEncodedText = base64EncodedText.Replace("=", String.Empty).Replace('+', '-').Replace('/', '_');
URLのBase64へのガイド StackOverflowエントリを見ましたが、既知の長さであるため、最後に必要な等号の数をハードコーディングできます。
解決
これは正しくパディングする必要があります:-
base64 = base64.PadRight(base64.Length + (4 - base64.Length % 4) % 4, '=');
他のヒント
URLセーフなBase64エンコードおよびデコードを処理しているUrlTokenEncodeおよびUrlTokenDecodeメソッドを使用して、クラス HttpServerUtility もチェックします。
注1:結果は有効なBase64文字列ではありません。 URLの一部の安全でない文字が置き換えられます。
注2:結果はRFC4648のbase64urlアルゴリズムとは異なります。
///<summary>
/// Base 64 Encoding with URL and Filename Safe Alphabet using UTF-8 character set.
///</summary>
///<param name="str">The origianl string</param>
///<returns>The Base64 encoded string</returns>
public static string Base64ForUrlEncode(string str)
{
byte[] encbuff = Encoding.UTF8.GetBytes(str);
return HttpServerUtility.UrlTokenEncode(encbuff);
}
///<summary>
/// Decode Base64 encoded string with URL and Filename Safe Alphabet using UTF-8.
///</summary>
///<param name="str">Base64 code</param>
///<returns>The decoded string.</returns>
public static string Base64ForUrlDecode(string str)
{
byte[] decbuff = HttpServerUtility.UrlTokenDecode(str);
return Encoding.UTF8.GetString(decbuff);
}
コメントするのに十分なポイントではありませんが、役立つ場合、提供されたリンク(JSON Web Signature ietfドラフト)でSushilが見つけたコードスニペットは、Base 64をURLのパラメーターとしてエンコードするときに機能します。
怠zyな人のために以下のスニペットをコピー:
static string Base64UrlEncode(byte[] arg)
{
string s = Convert.ToBase64String(arg); // Regular base64 encoder
s = s.Split('=')[0]; // Remove any trailing '='s
s = s.Replace('+', '-'); // 62nd char of encoding
s = s.Replace('/', '_'); // 63rd char of encoding
return s;
}
static byte[] Base64UrlDecode(string arg)
{
string s = arg;
s = s.Replace('-', '+'); // 62nd char of encoding
s = s.Replace('_', '/'); // 63rd char of encoding
switch (s.Length % 4) // Pad with trailing '='s
{
case 0: break; // No pad chars in this case
case 2: s += "=="; break; // Two pad chars
case 3: s += "="; break; // One pad char
default: throw new System.Exception(
"Illegal base64url string!");
}
return Convert.FromBase64String(s); // Standard base64 decoder
}
質問で説明されているように、base64とはほとんど異なるbase64urlエンコーディングのエンコード/デコードを行うコードを探しているときにここをヒットしました。
このドキュメントにc#コードスニペットが見つかりました。 JSON Web Signature ietfドラフト
受け入れられた答えと比較して、C#を使用してbase64でエンコードされたURLを基本的にデコードする方法は次のとおりです。
デコード:
string codedValue = "base64encodedUrlHere";
string decoded;
byte[] buffer = Convert.FromBase64String(codedValue);
decoded = Encoding.UTF8.GetString(buffer);