Cryptography Encrypt ve decrypt ile ilgili güzel bir makale
Cryptography güvenilir olmayan kanallarda güvenli bir bilgi akışı sağlar. Var olan data matamatiksel olarak değiştirilerek yollanır. Böylece dışarıdan bilgi hırsızlığı önlenmiş olur. Tabi ki bu işlemler bilgi alışverişinde bir yavaşlamaya sebep olur. Ama bazı durumlarda buna katlanılması gerekir. Cryptography temel olarak dört kısma ayrılır. bunlar; Private-Key Encryption(symmetric cryptography), Public-Key(asymmetric cryptography) Encryption, Cryptographic signing, Cryptographic hashes.
Private-Key Encryption
Bu encryption algoritması bir tek anahtar ile bilgiyi encrypt ve decrypt eder. Burada anahtar gizlenir, sadece bilgi alışverişini yapan kullanıcılar bu anahtarı bilirler. Public-Key algoritmasına nazaran daha hızlıdır. Bilgiler kısımlara ayrılarak encrypt edilir. Bu kısımlara ayırma da bir standarta sahiptir. Eğer bir kısmı n byte kabul edersek, n=8 byte RC2,DES ve TripleDES; n=16(varsayılanı),n=24 veya n=32 byte Rijndael algoritmaları kullanılır. Bu algoritmalara göre de anahtar kullanmamız gerekir. Örneğin 16 byte'lık kısımlara ayıracak isek Rijndel algoritması kullanacağız demektir. Bu da bir crypt zamnında 16 byte'lık veriyi encrypt veya decrypt yapacağımız manasına gelmektedir. anahtarımız da bu na göre 16 byte dan oluşmalıdır. örneğin:
Dim Key As Byte() = {69, 110, 99, 111, 100, 105, 110, 103, 32, 83, 116, 114, 105, 110, 103, 46}
olabilir. Eğer bilgi hırsızları sizin datanız hakkında tüm bilgileri biliyorlarsa (yani işinin ehli ise) bu şifrelemeyi de çözebilirler. Bunun için bir başlangıç vektörü kullanılır bu da kısımlar içindir ve bu da sadece bilgi alışverişini kullanan kullanıcılar tarafından bilinir. Örneğin:
Dim IV As Byte() = {69, 110, 99, 111, 100, 105, 110, 103, 32, 83, 116, 114, 105, 110, 103, 46}
Şimdi gelin bir senaryo yazalım. Ali ile Veli karşılıklı haberleşecekler. Ali Veli ye Selam mesajını gönderecek. Bu mesajı da bir interceptor yani bilgi hırsızı okumaya çalışacak o da Coni olsun.
VS.Net'te File->New->Project ve Console Application seçin ve aşağıdaki kodu içerisine yazın. Veya Not Defterinde yazın ve vbc.exe ile derleyin.
Imports System
Imports System.IO
Imports System.Security.Cryptography
Imports System.Net.Sockets
Module Module1
Sub Main()
Try
'TCP kullanıcısı tanımlanır.
'localhost default IP adresidir
Dim TCP As New TcpClient("localhost", 11000)
'TCP bağlantısından bir network stream tanımlanır.
Dim NetStream As NetworkStream = TCP.GetStream()
'Rijndael protokolü tanımlanır
'bu protokol mesajın kısımlara ayrılıp (16,24,32 bytes)
'crypt edilmesini sağlar.
Dim RMCrypto As New RijndaelManaged()
'Anahtar ve Başlangıç Vektörü byte dizisi olarak tanımlanır
'Bunlara hexal olarak (Örneğin 0x11) veya decimal olarak ilk değer
'aktarılır. 16 byte varsayılandır.
Dim Key As Byte() = {69, 110, 99, 111, 100, 105, 110, 103, 32, 83, 116, 114, 105, 110, 103, 46}
Dim IV As Byte() = {69, 110, 99, 111, 100, 105, 110, 103, 32, 83, 116, 114, 105, 110, 103, 46}
'CryptoStream(Bilgi Stream nesnesi,Crypt Yöneticisi,Crypt Modu)
'esas işlem bu kodda yapılır
Dim CryptStream As New CryptoStream(NetStream, RMCrypto.CreateEncryptor(Key, IV), CryptoStreamMode.Write)
'Daha sonra normal bir stream nesnesine aktarılır
've pişmiş yemeği yemekten başka bir işimiz kalmıyor.
Dim SWriter As New StreamWriter(CryptStream)
'Mesajımızı stream nesnesine yazıyoruz
SWriter.WriteLine("Selamun Aleykum"
'Ve consola mesaj gitti diye yazıyoruz.
Console.WriteLine("Mesaj yollandı"
SWriter.Close()
CryptStream.Close()
NetStream.Close()
TCP.Close()
Catch
'Eğer hata varsa
Console.WriteLine("Bağlantı Sağlanamadı"
End Try
End Sub
End Module
Senaryoya göre bu Ali'nin kullanacağı program gelin Veli'nin programını da yazalım ve daha sonra ne yaptığımızı ve nasıl kullanacağımızı inceleriz.
Yeni bir Console projesi daha açın ve aşağıdaki kodu modülün içerisine yazın.
Imports System
Imports System.Net.Sockets
Imports System.Threading
Imports System.IO
Imports System.Security.Cryptography
Module Module1
Sub Main()
'ilk olarak anahtar ve başlangıç vektörünü tanımlayalım
'bunların alacağı ilk değerler diğer program ile aynı olması gerekiyor.
Dim Key As Byte() = {69, 110, 99, 111, 100, 105, 110, 103, 32, 83, 116, 114, 105, 110, 103, 46}
Dim IV As Byte() = {69, 110, 99, 111, 100, 105, 110, 103, 32, 83, 116, 114, 105, 110, 103, 46}
Try
'Bu sefer bir dinleyici ile belirtilen port dinlenir
'bu port aynı zaman da diğer program tarafından mesaj
'göndermek amaçlı kullanılır.
Dim TCPListen As New TcpListener(11000)
'Dinlemeyi başlat
TCPListen.Start()
'Her beş saniyede bir port dinlernir
'taki mesaj yollanana dek dinlenir
'eğer hata olursa kesmek için Ctrl-C tuşlarını kullanın
While Not TCPListen.Pending()
Console.WriteLine("Her 5 saniyede bir port dinleniyor."
Thread.Sleep(5000)
End While
'Kullanıcı kabul edilir
Dim TCP As TcpClient = TCPListen.AcceptTcpClient()
'Belirtilen network bağlantısının bir stream nesnesi tanımlanır.
Dim NetStream As NetworkStream = TCP.GetStream()
'Decrypt için yine aynı yönetim protokolü kullanılır.
Dim RMCrypto As New RijndaelManaged()
'Ve decrypt işlemi belirtilen anahtar ve başlangıç vektörü ile yapılır.
Dim CryptStream As New CryptoStream(NetStream, RMCrypto.CreateDecryptor(Key, IV), CryptoStreamMode.Read)
'stram okuyucuya aktarılır
Dim SReader As New StreamReader(CryptStream)
Console.WriteLine("Yollanan Mesaj: {0}", SReader.ReadToEnd())
SReader.Close()
NetStream.Close()
TCP.Close()
Catch
Console.WriteLine("Dinleyicide hata"
End Try
End Sub
End Module
Programları iki ayrı konsolda çalışması gerekir. ilk önce decrypt yapan program yani senaryoya göre Veli'nin programı çalışması gerekir. daha sonra encrypt yapan program yani Ali'nin programını çalıştırın ve mesaj gönderilsin. Yine senaryoya göre Coni'nin Veli'nin programı gibi bir dinleyici programı olduğunu düşünelim. Burada eğer anahtarın sadece bir baytı bile değişse bilgi yanlış çevrilecek ve programın hataya düşmesine sebep olacaktır. Umarım Ali, Veli diye aklınızı karıştırmamışımdır. Amacım Bu karmaşık işlemleri basitleştirmek. Yukarıdaki işlemler Private-Key yani senkronize olarak bir bilginin gönderilmesi olayından ibarettir. programda Tcp dinleyicisi kullanmak önemli değildir. sadece bir stream nesnesinin kullanılması gerekir (Örneğin FileStream). Esas can alıcı nokta CryptoStream nesnesinin tanımlanmasında gerçekleşir. Parantez içinde çevirilecek Stream nesnesi, Çevirme şekli yöneticisi ve çevirme modu yer alır. İşlem burada gerçekleşir ve burada çevirlir. daha sonra bizim kullanmamız için gerekli stream okuyucusu veya yazıcısına aktarılır. Bundan sonra tek yapmamız gereken mesajı kullanmaktır.
Private-Key kullanımının dezavantajı mesajı yollayan ve alanın üzerinde anlaşacağı bir anahtarın kullanılmasıdır. Bu kullanımda anahtarın deşifre olması programın tamamen güvenliksiz hale gelmesi demektir. Gerçek uygulamalarda Private-key ve Public-key seçenekleri beraber kullanılırlar. Gerçek uygulama örneklerine geçmeden önce biraz da Public-Key Encryption seçeneğine göz atalım.
Public-Key Encryption
Public-Key de aslında bir Private key kullanır. Birbirlerine bağımlıdırlar. Public Key ile encrypt edilmiş data sadece private keyi ile decrypt edilebilir be o Private key ile imzalı data sadece public key'i ile doğrulanabilir. Aklınız karışmasın gelin kullanılışına bakalım.
Yeni bir console projesi açın ve modülün içerisine aşağıdaki kodları yazın.
Imports System
Imports System.IO
Imports System.Security.Cryptography
Imports System.Text
Module Module1
Public Sub Main()
'encrypt işleminden çıkan datayı kaydetmek için
' bir FileStream nesnesi tanımlanır
Dim fs As New FileStream("Dosya.txt", FileMode.Create, FileAccess.Write)
Console.Write("Dosyaya Encrypt edilerek kaydedilecek yazıyı Girin:"
Dim strgiris As String = Console.ReadLine()
'DES nesnesi rastgele bir anahtar ile tanımlanır
Dim des As New DESCryptoServiceProvider()
'des sağlayıcısında yeni bir encryptor açılır ve filestream
'değişkenimiz ile ilişkilendirilir. Bu ilişki CryptoStream
'sınıfı ile kullanılır. artık bir bilgi girişi için bu nesne
'ile tanımladığımız değişken kullanılır. Ve her girdiğimiz bilgi
'encryptlenerek dosya.txt dosyasına yazılır.
Dim iliskistream As New CryptoStream(fs, des.CreateEncryptor(), CryptoStreamMode.Write)
'Klavyeden girdiğimiz string bilgi byte dizisine çevrilir
'fonksiyon ancak byte dizisi kabul eder.
Dim bytedizisi As Byte() = (New UnicodeEncoding().GetBytes(strgiris))
iliskistream.Write(bytedizisi, 0, bytedizisi.Length)
iliskistream.Close()
'encrypt edilerek tanımlanan dosya stream açılır
Dim fsread As New FileStream("dosya.txt", FileMode.Open, FileAccess.Read)
'encrypt edilen dosya decrypt edilmesi için tekrar bağlanır
'burada decrypt işlemi gerçekleşir
Dim iliskistreamDecr As New CryptoStream(fsread, des.CreateDecryptor(), CryptoStreamMode.Read)
'decrypt edilen bilgi ekrana basılır.
Console.WriteLine(New StreamReader(iliskistreamDecr, New UnicodeEncoding()).ReadToEnd())
Console.WriteLine()
Console.WriteLine("Devam etmek için bir tuşa basın..."
Console.ReadLine()
End Sub
End Module
Gerçek programlarda ne Public key yalnız kullanılır nede Private Key. Public Key Private Key'e göre yavaştır. Sadece anahtar veya ona benzer küçük verilerin taşınmasında kullanılır. Private Key de verinin gönderilmesi aşamasında kullanılır. Gelin bir senaryo daha yazalım. Ve kullanılışını anlamaya çalışalım.
Yine Ali ve Veli devrede. ilk olarak Veli public/private key çiftini yönetir. Eğer Ali Veli ye encrypt edilmiş mesajı göndermek istiyorsa, Ali, Veli ye Public Key'ini sorar. Veli, Ali'ye güvenliksiz kanaldan Public key'i yollar ve Ali bu key'i kullanarak bir mesaj encrypt eder ve yollar. Veli de private key'i kullanarak bu mesajı okur.
Tabii bu sırada Coni'nin boş durmadığını varsayalım. Veli'nin public key'i güvenliksiz kanalda Coni tarafından alınabilir. Hatta Coni daha ileriye gidip Ali'nin mesajınının yollanmamasını sağlayabilir. Ama Coni mesajı Veli'nin Public key'i ile decrypt edemez. Mesaj sadece Veli'nin o yollanmayan private key'i ile decrypt edilebilir. Veli de Ali ye cevap göndermek isterse o da Ali'nin Public Key'ini ister ve o na göre mesajını yollar. Burada aklınıza şöyle bir soru gelebilir. Niye Public key ile encrypt edilen mesaj Public Key'i elde eden Coni tarafından okunamıyor. Bu sır kullanılan DESCrypto servis sağlayıcısının oturumunda saklıdır. Public Key sadece Private key ile kullanılmaz örneğin Dijital imza kullanan programlarda da kullanıcıların tanınması aşamasında kullanılabilir. İyi çalışmalar.