Makale Özeti

Microsoft .Net ve Şifreleme üzerine makale

Makale

Şifreleme Nedir ?
Şifreleme; temel olarak sahip olunan bilgilerin herkes tarafından kolayca görülmesini veya değiştirilmesini engellemek için kullanılan bir yöntemdir.
Günümüzde en önemli uygulama alanı olarak haberleşme gösterilebilir. İster askeri amaçla bilgi transferi yapılıyor olsun, ister halka açık ve güvensiz bir ortam olan Internet üzerinden bilgi aktarılımı yapılsın eğer aktarılan, herkesin açıkça öğrenmesi istenmeyen bir bilgi ise çeşitli şifreleme teknikleri kullanılarak bu bilginin haberleşme kanallarında gidip gelirken çalınarak istenmeyen kişilerin eline geçmesi engellenmeye çalışılır.

Şifreleme (Kriptoloji), temelde matematiğe dayalı, oldukça karmaşık formülasyon ve bilgi dönüşümleri içeren ve başlı başına bir teknolojik bilim dalı olarak gelişen cok detaylı ve geniş bir sistematiktir.

Şifrelemenin ve şifrelemede elektronik cihazlar kullanımının önemi 2. dünya savaşında askeri haberleşmenin güvenli hale getirilerek doğru ve güvenilir bir emir komuta zincirinin oluşturulması ihtiyacı ortaya çıktığında anlaşılmıştır.

2. Dünya savaşı sonrasında hemen her ülke kendi şifreleme standardizasyon ve organizasyonlarını oluşturma çabası içine girmiştir. Daha sonraları da uluslararası birtakım kuruluşlar bu işleri organize etmeye başlamıştır.

Günümüzde Şifreleme
ABDde National Institute of Standards and Technology (NIST) adlı bir kuruluş tarafından, geçmişten bugüne kadar geliştirilen tüm şifreleme teknikleri ve uygulamaları kayıt altına alınmış ve daha güvenli yöntemler bulunabilmesi amacıyla çeşitli çalışmalar yapılmaktadır.

Bu amaçla 1997de bu kuruluş tarafından; yeni ve en güvenilir şifreleme algoritmasını geliştirebilmek amacıyla bir standart oluşturma çalışması başlatılmıştır. Birtakım standartlar belirlenmiş ve bu standartlar AES (Advanced Encryption Standarts) adı altında birleştirilerek, Tüm dünyadaki matemetikçilere ve güvenlik kuruluşlarına açık bir yarışma duyurulmuştur.

1998 Ağustosunda ilk 15 finalist belirlenmiştir. Daha sonra bu finale kalan algoritmalar arasında yaklaşık bir yıl süren bir inceleme yapılarak finalist sayısı 5e düşürülmüştür.
Bu beş finalist algoritma şunlar olmuştur.
- MARS (IBM tarafından geliştirildi)
- RC6 (RSA Güvenlik Lab. Tarafından geliştirildi.)
- Rijndael (Joan Daemen, Vincent Rijmen adlı Matematikçilerce Geliştirildi.)
- Serpent (Ross Anderson, Eli Biham, Lars Knudsen adlı Matematikçilerce Geliştirildi.)
- Twofish (Bruce Schneier, John Kelsey, David Wagner adlı Bilim adamlarınca Geliştirildi.)

2000 Yılının ortalarında da nihayet yarışma sonuçlanmış, Rijndael Algoritması birinci seçilerek AES Standardı olarak kabul edilmiştir.
Şu anda en gelişmiş simetrik şifreleme algoritması olarak Rijndael Algoritması gözükmektedir ve ABD hükümetince de onaylanmış güvenlik standardı olmuştur.

Şifreleme Unsurları Nelerdir ?
Şifrelemede 3 ana unsur vardır. Birincisi Şifrelenecek Bilgi, İkincisi Bir Şifreleme Algoritması, Üçüncüsü de Bu Algoritmada kullanılacak Şifreleme Anahtarıdır.
Yüzlerce şifreleme algoritması vardır. Ancak hepsinin ana hedefi, Şifreleme anahtarına sahip olunmadan, Şifrenin çözülerek Şifrelenen Bilgiye ulaşılmasını engelleyebilmektir.
.Net Framework, Şifreleme algoritmalarının tüm karmaşıklığını kendi içerisinde bloklayarak, programcılara Ortak bir Arayüz Sağlar, ve tüm bu şifreleme teknikleri Microsoft CrytpoAPI içerisinde gerçekleştirilerek desteklenir.

Temel olarak iki tip şifreleme tekniği vardır:
1- Public Key Encryption (Açık Şifre Anahtarlı Şifreleme)
Asimetrik Şifreleme olarak da bilinir. Şifreleme için Gizli bir Şifreleme anahtarı ve Deşifreleme için de (Yetkili olan) herkesin bildiği bir açık anahtar kullanılır. Deşifreleme ancak, Şifrelemede kullanılan Gizli anahtara uygun bir Deşifre anahtarı kullanıldığında mümkün olur. Deşifreleme anahtarları bir kullanımlık ya da defalarca kullaımak üzere tasarlanabilir.
Asimetrik şifreleme algoritması Ancak Kısa ve Küçük Miktarlardaki Bilgilerin Şifrelenmesi için uygundur.
Microsoft .Net Framework içerisinde aşağıdaki Asimetrik Şifreleme Algoritmaları sunulmaktadır :
- Digital Signature Algorithm (DSA)
- RSA

2- Private Key Encryption (Gizli Şifre Anahtarı Şifreleme)
Simetrik Şifreleme olarak da bilinir. Şifreleme ve Deşifre etme tek bir ortak anahtarla yapılır. Simetrik şifreleme teknikleri oldukça hızlıdır ve bu nedenle Uzun ve Büyük Miktarlardaki verilerin şifrelenmesinde kullanışlı olmaktadır. Simetrik şifreleme algoritmaları Blok Şifreleme teknikleri olarak da bilinir, çünkü bu algoritmalar verileri bloklar halinde şifrelerler. Zaten hızlı olmalarının altında yatan önemli bir neden de budur.
Eger şifrelenmiş verinin yapısı anlaşılır ve içindeki patternler bulunabilirse, Ters mühendislik ile anahtarların bulunarak verilerin deşifre edilmesi mümkün olabilir.

Bunu engellemek için .Net Framework içerisinde Zincirleme(Chaining) adı verilen bir teknikle bir önceki bloğun şifrelenmesinde kullanılan Vektörler bir sonrakine esas teşkil etmekte ve şifrelenen verinin yapısının kolayca çözülmesi engellenmektedir.
Bu nedenle ilk bloğun şifrelenmesi için de bir başlangıç vektörüne (Initialization Vector) ihtiyaç duyulmaktadır.
Aşağıda Microsoft .Net Framework içerisinde yer alan simetrik şifreleme algoritmaları ve çok kısa açıklamaları yer almaktadır:

- DES (Data Encryption Standard)
Verileri 64 bitlik bloklar halinde şifreler, 64 bitlik (8 karakter) anahtar kullanır. Anahtar 64 bitliktir ancak efektif anahtar gücü 56 bitlik (7 karakter) olarak kabul edilmektedir.
Günümüzde, DES algoritmasını kırmak için çeşitli elektronik donanımlar geliştirilmiştir.
Bu nedenle DES algoritması artık güvenilir kabul edilmemektedir.


- RC2
Değişken anahtar uzunluklu (8 ila 64 bit) bir şifreleme algoritmasıdır. DES algoritmasının yerini alması amacıyla tasarlanmıştır. DES algoritmasından 3 ila 6 kat daha hızlıdır.
Ancak 8 karakterlik(64 bit) anahtar uzunluğu, Deneme yanılma (Brute Force Attack) metoduyla çözülebilmesine olanak sağladığı için güvenli sayılmamaktadır.
- Triple DES
DES algoritmasının ardada üç kez uygulanması temel mantığı ile çalışmaktadır.
DES algoritmasına göre daha güvelidir. Ancak 3 kez daha yavaş olduğu da kolayca anlaşılabilir.
- Rijndael - Advanced Encryption Standard (AES)
DES algoritmasının yerini alan ve AES standardı olarak kabul edilen algoritmadır. 128, 192 , 256 veya 512 bitlik anahtar uzunlukları için kullanılabilmektedir.
Şu anda en güvenli ve hızlı şifreleme algoritması olarak tanımlanmaktadır.
Kişisel olarak benim de uzun araştırmalar sonucu en güvenilir olduğuna kanaat getirdiğim ve örnek kodlarımda kullandığım algoritma budur.
- Hashing Algoritmaları
Hashing algoritmaları, uzunluğu ne olursa olsun tüm şifrelenecek veriler için aynı uzunlukta bir karakter dizisi oluşturmak mantığı ile çalışırlar.
Hashing algoritmaları aynı zamanda tekil sonuçlar üretirler. Yani iki veri arasında tek bir harf dahi farklı olsa farklı bir karakter dizisine dönüşürler.
Hashing algoritmaları oldukça karmaşık ve uzun algoritmalardır.
Detayına girmeden Microsoft .Net Framework içerisinde desteklenen hashing algoritmalarının listesini yaparsak;
- HMACSHA1
- MACTripleDES
- MD5CryptoServiceProvider
- SHA1Managed
- SHA256Managed
- SHA384Managed
- SHA512Managed

Örnek

BossNet Şifreleme Kutuphane Sınıfı
Aşağıdaki Visual Basic Kutuphane Sınıfı,
Hemen her türlü uygulamada kullanılabilecek bir örnek kod kütüphanesi sınıfı olarak tasarlanmıştır.
Kolay anlaşılması için , Key ve Initialization Vector ler sabit olarak sınıfın içinde gömülüdür.
Bu iki değişken, sınıfın işlevlerine parametre olarak da gönderilebilir. Ya da kullanılacağı yere uygun olarak daha başka tasarımlar da yapılabilir.
- Init Vector ve Key için 2 tane Property tanımlanmıştır.
- Encrypt(Şifrele) ve Decrypt(Çöz) adıyla da iki işlev tanımlanmıştır.
Her ikisi de parametre olarak üzerinde işlem yapılacak olan Stringi almakta ;
Dönüş değeri olarak da şifrelenmiş veya çözülmüş olarak başka bir String geri dönmektedir.

Encypt() işlevinde,
.Net Şifreleme Sınıfları, Byte dizileriyle çalıştığı için, önce gelen Stringi byte dizilerine çevirmek gerekli. Bu işlemi yaparken, kodun çalıştığı bilgisayarın varsayılan karakter encodingini kullanmak için system.text sınıfının,
System.Text.Encoding.Default.GetBytes(_String.ToCharArray) işlevini kullandım.
Daha sonra engine olarak RijndaelManaged kullanarak,
başka bir değişkende oluşturduğum bir MemoryStream üzerinde
bir Encryption CryptoStream oluşturdum.
Ve bu CryptoStreamin Write metoduyla şifrelenmiş bytelari hazırladım.
Daha sonra da
System.Convert.ToBase64String(_EncodedBytes) işlevini kullanarak, elde ettiğim şifrelenmiş byte dizisini Stringe dönüştürerek geriye döndüm.

Decrypt() işlevinde,
.Net Şifreleme Sınıfları, Byte dizileriyle çalıştığı için, önce gelen Stringi byte
dizisine System.Convert.FromBase64String(_String) işlevini kullanarak çevirdim.
Daha sonra engine olarak RijndaelManaged kullanarak,
başka bir değişkende oluşturduğum bir MemoryStream üzerinde
bir Decryption CryptoStream oluşturdum.
Ve bu CryptoStreamin Read metoduyla şifrelenmiş byte dizisini, InitialString adlı değişkenle tanımladığım byte dizisine şifresi çözülmüş olarak okudum.
Daha sonra da bu byte dizisini, tanımladığım bir StringBuilder yardımıyla Stringe dönüştürerek geriye döndüm.

Bu işlevlerde, Amaca göre, Memory Stream yerine File Stream ya da Network Stream gibi diğer herhangi bir Stream sınıfı kullanılabilirdi.

BossCrypter in Kullanımı
Kutuphane sınıfının kulanımı oldukça basittir :

Dim AdSoyad As String = "Süleyman NALCI"
Dim EncEngine as new BossNet.Security.BossCrypter()
Dim SifreliAdSoyad As String = EncEngine.Encypt(AdSoyad)

BossCrypter in Kaynak Kodu

Imports System.Security.Cryptography

Imports System.IO

#######################################

#######################################

Namespace BossNet.Security

   Public Class BossCrypter

        Private Shared keyb() As Byte = _

        {1, 253, 5, 50, 52, 91, 193, 123, 193, 122, 211, 164, 57, 128, 91, 91, _

        19, 46, 88, 197, 125, 98, 67, 48, 97, 154, 83, 187, 222, 34, 171, 74}

        Private Shared ivb() As Byte = _

        {110, 61, 235, 100, 121, 120, 80, 208, 13, 82, 196, 212, 176, 46, 23, 85}

#Region "Variables"

        Private Engine As New RijndaelManaged()

        Private m_IV() As Byte, m_Key() As Byte

#End Region

#Region "Initialize"

        Public Sub New()

            With Engine

                m_IV = ivb .Init.Vector

                m_Key = keyb .Key

            End With

        End Sub

#End Region

#Region "Properties"

        Friend Property IV() As String

            Get

                Dim StrBuilder As New System.Text.StringBuilder(), i As Integer

                For i = 0 To m_IV.Length - 1

                    StrBuilder.Append(ChrW(m_IV(i)))

                Next

                Return StrBuilder.ToString

            End Get

            Set(ByVal Value As String)

                m_IV = System.Text.Encoding.Default.GetBytes(Value.ToCharArray)

            End Set

        End Property

        Friend Property Key() As String

            Get

                Dim StrBuilder As New System.Text.StringBuilder(), i As Integer

                For i = 0 To m_Key.Length - 1

                    StrBuilder.Append(ChrW(m_Key(i)))

                Next

                Return StrBuilder.ToString

            End Get

            Set(ByVal Value As String)

                m_Key = System.Text.Encoding.Default.GetBytes(Value.ToCharArray)

            End Set

        End Property

#End Region

#Region "Enrypt-Decrypt"

        Friend Function Encrypt(ByVal _String As String) As String

            Dim _EncodedBytes() As Byte = {}, MemStream As New MemoryStream()

            Dim _Bytes() As Byte = System.Text.Encoding.Default.GetBytes(_String.ToCharArray)

            Dim CryStream As New CryptoStream(MemStream, Engine.CreateEncryptor(m_Key, m_IV), CryptoStreamMode.Write)

 

            Try

                CryStream.Write(_Bytes, 0, _Bytes.Length)

                CryStream.FlushFinalBlock()

                _EncodedBytes = MemStream.ToArray

                MemStream.Close()

                CryStream.Close()

            Catch exc As Exception

                MsgBox(exc.Message)

                MemStream.Close()

                CryStream.Close()

            End Try

            Return System.Convert.ToBase64String(_EncodedBytes)

        End Function

 

 

        Friend Function Decrypt(ByVal _String As String, Optional ByVal _FromCulture As System.Globalization.CultureInfo = Nothing) As String

            Dim _Bytes() As Byte = System.Convert.FromBase64String(_String)

            Dim _InitialText() As Byte : ReDim Preserve _InitialText(_Bytes.Length)

            Dim MemStream As New MemoryStream(_Bytes)

            Dim CryStream As New CryptoStream(MemStream, Engine.CreateDecryptor(m_Key, m_IV), CryptoStreamMode.Read)

 

            Try

                CryStream.Read(_InitialText, 0, _InitialText.Length)

                CryStream.FlushFinalBlock()

                MemStream.Close()

                CryStream.Close()

            Catch exc As Exception

                MemStream.Close()

                CryStream.Close()

            End Try

            Dim StrBuilder As New System.Text.StringBuilder(), i As Integer

            For i = 0 To _InitialText.Length - 1

                StrBuilder.Append(ChrW(_InitialText(i)))

            Next

            Return StrBuilder.ToString

        End Function

#End Region

 

    End Class

End Namespace

 

NOT : Bu yazı okuyucunun "Nesne Tabanlı Programlama" ve "VB.NET" ile ilgili çok temel kavramları bildiği varsayılarak hazırlanmıştır.

Süleyman NALCI (Anadolu Grubu Bilgi Sistemleri BOSS.NET Proje Grubu)
e-Posta : suleyman.nalci@efespilsen.com.tr