URL'de Güvenli Şifreleme

Şifreleme tekniklerini URL'de (QueryString de dahil) kullanmak isterseniz dikkat etmeniz gereken bir konu var.

Eğer şifrelediğiniz bilgileri URL'de kullanmak veya QueryString üzerinden bir başka sayfaya taşımak istiyorsanız aşağıdakine benzer bir url oluşma ihtimali vardır.

http://www.abc.com/TIRlcEq0umjO6uJqtqvnkUGntUzv19rK+8mcvPK5qL1bwEZtEUqTlc3iF/TomuXU746Il5IF2iN9SeYuYDqt6SQzfdrv+Ltug2KZteKlYawc=

Sorun yokmuş gibi görünüyor ama '+', '/', ve '=' karakterleri IIS için tehlikleli karakterlerdir ve bu durumda aşağıdaki hatayı alma ihtimaliniz vardır.

HTTP Error 404.11 - Not Found
The request filtering module is configured to deny a request that contains a double escape sequence.

Bu sıkıntıyı gidermek için basit bir karakter değiştirme operasyonu yapmalıyız. 

Ben bu sıkıntıyı gidermek için şu static class ı kullanıyorum:

public static class SafeBase64UrlEncoder
{
	private const string Plus = "+";
	private const string Minus = "-";
	private const string Slash = "/";
	private const string Underscore = "_";
	private const string EqualSign = "=";
	private const string Pipe = "|";
	
	private static readonly IDictionary<string, string> _mapper;
	static SafeBase64UrlEncoder()
	{
		_mapper = new Dictionary<string, string> 
		{ 
			{ Plus, Minus }, 
			{ Slash, Underscore }, 
			{ EqualSign, Pipe } 
		};
	}
	public static string EncodeBase64Url(string base64Str)
	{
		if (string.IsNullOrEmpty(base64Str)) return base64Str;
		foreach (var pair in _mapper)
			base64Str = base64Str.Replace(pair.Key, pair.Value);
		return base64Str;
	}
	public static string DecodeBase64Url(string safe64Url)
	{
		if (string.IsNullOrEmpty(safe64Url)) return safe64Url;
		foreach (var pair in _mapper)
			safe64Url = safe64Url.Replace(pair.Value, pair.Key);
		return safe64Url;
	}
}

Class'ın yaptığı iş kısaca, IIS için tehlike oluşturan karakterleri güvenli ve şifreleme sonunda asla oluşturalamayacak karakterlere dönüştürmek.

Eskisi Yenisi
+ -
/ _
= |

Daha önceden "Kullandığım Şifreleme Sınıfım" başlıklı bir yazı yayınlamıştım. Bu sayfadaki şifreleme sınıfını aşağıdaki gibi güncelledim.

using System;
using System.IO;
using System.Security.Cryptography;
using System.Text;
using System.Web;
using System.Collections.Generic;

/// <summary>
/// Summary description for Sifreleme
/// </summary>
public static class Sifreleme
{
 ....
    public static string Sifrele(this string plainText, bool URLEncode)
    {
        if (URLEncode)
            return SafeBase64UrlEncoder.EncodeBase64Url(plainText.Sifrele());
        else
            return plainText.Sifrele();
    }

    public static string SifreCoz(this string cipherText, bool URLDecode)
    {
        if (URLDecode)
            return SafeBase64UrlEncoder.DecodeBase64Url(cipherText).SifreCoz();
        else
            return cipherText.SifreCoz();
    }
....
}

Bu değişiklikten sonra güvenli bir şekilde URL'de ya da QueryString'te verileri şifreleyerek kullanabilirsiniz.

Kolay gelsin.