Querystringlerinizi Şifreleyin
Etiketler :
asp.net vb.net querystring sifrele
Okunma Sayısı : 174
Yayınlanma Tarihi : 27.03.2008
Yayınlayan : Akın Bostancı
|
Bu Makaleye 0
kişi puan vermiştir. Ortalama Puan: 0 |
Özet :
Querystringlerinizde Id lerinizi herkes görmesin
Merhabalar
Bu yazımın konusu querystring güvenliği üzerine. Querystringde bulunan güvenlik açıklarını basitçe inceleyip daha sonra konu ile ilgili yazmış olduğum querystringi şifreleyen ve çözen bir classın kodlarını inceleyeceğiz.
Querystring sayfalar arasında veri taşımaya veya bir sayfayı gönderilen bir parametrik değere göre derletmeye veya iş yaptırtmaya yarayan ve sayfa adresinin sonuna ?den sonra eklenen parametredir. Querystringlerde enter karakteri, & karakteri (querystring ayıracı oldugundan dolayı) gibi bazı karakterleri taşımak mümkün değildir ancak yazacağımız şifreleme classı sayesinde bu karakterleride taşıyabilir hale geleceğiz.
Querystring browserda adres çubuğunda gözüktüğü için kullanıcının bunu değiştirmesi ve ona göre iş yaptırması mümkündür.Örnek verecek olursak;
Bir mesajlaşma sitemiz olduğunu düşünelim.Kullanıcı kendine gelen mesajları okumak için mesaja tıkladığında http://www.sitemiz.com/mesajOku.aspx?MesajId=234 gibi bir adresi tarayıcının adres çubuğunda görecektir. Ve sonda bulunan MesajId parametresine ait değeri 235 yaparak belkide bir başkasına gelmiş olan mesajı okuyabilecektir.Bunu engellemenin bir yoku mesajOku.aspx sayfası her yüklenirken Parametre olarak gönderilen MesajIdye ait olan değerin kullanıcının mesajlarından birine ait olup olmadığını kontrol ettirmektir.Bu yöntem her sayfa yüklenmesinde veritabanına bağlanacağından dolayı işlemci gücü bakımından maliyetlidir. Bir diğer yöntem ise 234 sayısını kullanıcıya şifreli olarak göstertmek yani sayfayı redirect yaparken veya post ederken MesajId parametresinin değerini bir şifreleme algoritmasından geçirerek şifrelemek ve hedef sayfada bu şifreyi çözmektir bu şifrenin çözülmesi ve şifrelenmesininde elbette işlemciye bir maliyeti olacaktır ancak veri tabanına erişirken yoğunluk yaratmamış olacağız ve gereksiz bağlantılar açıp kapamaktan kaçınacağız. Böylece kullanıcı Querystringde bulunan değeri direkt göremeyecek ve 235 sayısının nasıl kodlandığını bilmediğinden müdahele edemeyecektir.Bunların yanısıra birçok site arka planda çalışan Id leri kullanıcılara göstermek istemez.Bunun içinse querystring yine şifrelenmelidir.
Şifreleme algoritmasını gerçekleştiriken querystringde bulunması hataya sebep karakterler üretmekten kaçınmalıyız.Yani oluşturacağımız şifreler hep bir gurup değerden oluşmalı ve bunun dışına çıkmamalıdır. Bunun için ise güzel bir yöntem mod kullanarak bir şifreleme geliştirmektir. Vede querystring şifrelemelerini çok uzun karakterler üretecek şekilde yapmamakta fayda vardır.
Public Class QueryStringCryptography Function encrypt(ByVal textToEncrypt As String) As String Dim rnd As New Random Dim crypterNumber As Integer Dim level1Encrypted As Integer Dim encryptedText As String Dim encryptedDigit As String |
Classımızı tanımladıktan sonra şifreleme işlemini gerçekleşterecek olan fonksiyonumuzu metinsel parametre olarak şifrelenmek istediğimiz metni alacak ve geriye şifreli metni döndürecek şekilde tanımlıyoruz.Ve daha sonra şifreleyecek gizli numarayı,birinci seviyede şifrelediğimiz metni,şifreli metni ve şifreli karakterleri tutacağımız değişkenlerimizi tanımlıyoruz.
For i As Integer = 0 To textToEncrypt.Length - 1 crypterNumber = rnd.Next(65, 90) level1Encrypted = Asc(textToEncrypt.Substring(i, 1)) * crypterNumber encryptedDigit = ConvertBase(level1Encrypted, 10, 33) Select Case encryptedDigit.Length Case 1 encryptedDigit = "00" & encryptedDigit Case 2 encryptedDigit = "0" & encryptedDigit End Select encryptedText &= Chr(crypterNumber) & encryptedDigit Next
|
For döngüsündende anlaşılabileceği gibi şifrelenecek metinde bulunan her bir karakter için şifreleme işlemi tek tek gerçekleştirip for döngüsünün son satırında birleştirilecektir.Şimdi şifrelemenin mantığını inceleyelim;
Elde ettiğimiz tek haneli karakterin ascii kodunu her karakter için farklı olarak randomize üretiiğimiz bir sayı ile çarpıyoruz.(Randomize ürettiğimiz bu sayının sınırlarını 65 ile 90 arası tanımlıyoruz çünkü büyük harflerin ascii kodları bu aralıktadır.).
Çarpma işleminden sonra elimizde oluşan sayıyı 10luk sayma düzeninden 33lük sayma düzenine çeviriyoruz.*(Bu çevirme işlemi ile ilgili bilgi yaznın en sonunda verilecektir.)
Şifreleyeceğimiz sayı en fazla 255(en büyük ascii kodu) oldugundan vede randomize üretilecek sayımız en falza 90 olduğundan, çarpımlarının en büyük değeri 22950 olacaktır. Buda 33lük sayma düzeninde 3 basamakla tanımlanabilecek bir sayıya denk geldiğinden. 3 basamaktan az olarak şifrelenen karakterleri başlarına etkisiz eleman olan 0ı koymak suretiyle 3 basamaklı hale getiriyoruz.
Metni şifreleyen ve randomize üretilen bir sayı üretip buna göre şifrelemiştik, buda demek oluyorki şifreli metni çözmek için yine bu sayıya ihtiyaç duyacağız.O zaman bu sayıyıda bir şekilde şifreleyerek bu şifreli metnin içine dahil etmeliyiz. Bunun için izleyeceğimiz yöntem sayıyı rastgele üretirken verdiğimiz aralıktan orataya çıkacak vede şifreleyen sayıyı ascii koduna karşılık gelen karakter ile tanımlayacağız ve bunu her basamak için daha önceden ürettiğimiz 3er haneli gurupların başına ekleyeceğiz.
Return encryptedText End Function |
Fonksiyonumuzun geriye döndüreceği değeri tanımlıyoruz vede fonksiyonumuzu bitiriyoruz.
Şimdi ise querystringin gönderildiği sayfada şifresini çözen fonksiyonu inceleyelim.
Function decrypt(ByVal textToDecrypt As String) As String Dim encryptedDigit As String Dim level1Encrypted As Integer Dim crypterNumber As Integer Dim decryptedtext As String |
Fonksiyonumuzu metinsel parametre olarak şifreli metni alıp geriye şifresi çözülmüş metni döndürecek şekilde tanımlıyoruz ve şifreli karakteri,şifreleyen sayıyı ve şifresi çözülmüş metni tutacağımız değişkenleri tanımlıyoruz.
For i As Integer = 0 To textToDecrypt.Length / 4 - 1 encryptedDigit = textToDecrypt.Substring(i * 4, 4) crypterNumber = Asc(encryptedDigit.Substring(0, 1)) encryptedDigit = encryptedDigit.Substring(1, 3) If encryptedDigit.Substring(0, 2) = "00" Then encryptedDigit = encryptedDigit.Substring(2, 1) ElseIf encryptedDigit.Substring(0, 1) = "0" Then encryptedDigit = encryptedDigit.Substring(1, 2) End If level1Encrypted = ConvertBase(encryptedDigit, 33, 10) decryptedtext &= Chr(level1Encrypted / crypterNumber) Next |
Şifremiz her karakter başına 4 karakterden(ilk karakter şifreleyen gizli sayının karakteri) oluştuğu için gelen şifreli metini dört hane dört hane inceleyip şifreleri parça parça çözerek sonda birleştireceğiz.Buna göre for döngüsünü yazıyoruz.
İlk karakteri alıp şifresini çözerek şifreleyen gizli sayıyı elde ediyoruz. Daha sonra geri kalan üç hanelik grubun başında 0lar varsa bunları atıyoruz(şifrelerken üç haneden az oluşan şifre parçacıklarını üç haneye tamamlamak için eklediğimiz 0 lar).
Daha sonra elde ettiğimiz sayıyı 33lük sayma düzeninden 10luk sayma düzenine çeviriyoruz. *
Son adımda ise şifreleyen sayıya bölüp şifrelediğimiz karakterin ascii kodunu buluyoruz. Buradanda karaktere geri dönüşüm yapıyoruz. Bu işlemi 4erli her gurup için yapıp birleştirdiğimizde şifreli metnin şifresini çözmüş oluyoruz.
Return decryptedtext End Function |
Çözdüğümüz şifrenin değerini geriye döndürerek fonksiyonu bitiriyoruz.
Aşağıda bulunan fonksiyonun görevi sayıların tabanlarını değiştirmektir.Bu fonksiyon ilgili ayrıntılı bilgiye ve çalışma mantığına daha önceden yazmış olduğum bir yazıdan ulaşabilirsiniz.Bu makaleye ulaşmak için tıklayınız.
Ancak belirttiğim makaleden ufak bir farkı vardır oda burada 33 elemandan oluşan bir dizi kullanılarak 33lük sayma tabanı işlemi yapabilme yeteneğidir.
Public Function ConvertBase(ByVal NumberToConvert As String, ByVal NumbersBase As Short, ByVal TargetBase As Short) As String Dim basesNumbers() As String = {"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "R", "S", "T", "U", "V", "Y", "Z"} Dim NumberConvertedTo10Base As Integer = 0 If NumbersBase = 10 Then NumberConvertedTo10Base = NumberToConvert Else For i As Integer = 0 To NumberToConvert.Length - 1 NumberConvertedTo10Base += basesNumbers.IndexOf(basesNumbers, NumberToConvert.Substring(NumberToConvert.Length - 1 - i, 1)) * Math.Pow(NumbersBase, i) Next End If Dim NumberConvertedToTargetBase As String If TargetBase = 10 Then NumberConvertedToTargetBase = NumberConvertedTo10Base.ToString Else Do Until NumberConvertedTo10Base = 0 NumberConvertedToTargetBase = basesNumbers((NumberConvertedTo10Base Mod TargetBase).ToString) & NumberConvertedToTargetBase NumberConvertedTo10Base = Math.Floor(NumberConvertedTo10Base / TargetBase) Loop End If Return NumberConvertedToTargetBase End Function End Class |
Tabiki bu fonksiyon çağırılırken try catch blokları içine yazıp bir hata oluşması durumunda kullanıcıyı bir hata sayfasına yönlendirmekte fayda vardır. Ayrıca güvenliği hiçbir zaman elden bırakmamak için yazının başında bahsettiğim olay olan gelen her parametreyi veri tabanında o kullanıcının erişebileceği bir veriye ait parametremi diye kontrol ettirmekte ve bu classı sadece id ler çok aleni bir şekilde görülmesini engellemek için kullanmakta fayda vardır.
Bu makalede bulunan classdaki şifreleyen sayıyı şifreleme tekniğini değiştirip daha karmaşık bir hale getirerek daha sağlam bir şifreleme elde edebilirsiniz.Veya şifreleyeceğiniz metni iki kademeli şifrelemeden geçirerek çok daha kararlı ve güvenli bir yapı elde edebilirsiniz.
ASP.NET Kategorisinden Son Makaleler
Makale ile ilgili Yorumlar
Yorum ekleyebilmeniz için üye olmanız gerekmektedir.
Üye iseniz üye girişi yapınız..
Üye değilseniz, üye olmak için tıklayınız