Merhaba arkadaşlar! Ben Aykut Selçuk Özkat. Bilkent Üniversitesi Bilgisayar Mühendisliği bölümünde 3. sınıf öğrencisiyim. E-bergi sayesinde sizlerle iletişim kurma fırsatı yakaladığım için çok mutlu ve gururluyum. Ben size yazılarımla katkıda bulunmaya çalışırken, sizler de bana e-posta yoluyla gönderebileceğiniz eleştiri ve tavsiyelerinizle yardımcı olabilirsiniz.
Kriptografi nedir?
Kriptografi; gizlilik, kimlik denetimi, bütünlük gibi bilgi denetimi kavramlarını sağlamak için çalışan matematiksel yöntemler bütünüdür. Bu yöntemler, bir bilginin iletimi esnasında karşılaşılabilecek aktif veya pasif ataklardan bilgiyi, dolayısıyla bilgi ile beraber bilginin göndericisi ve alıcısını da koruma amacı güderler. Kriptografik bir programın, içindeki bilgileri görme yetkisi olanlar dışındaki herkesten gizli tutması, kimlik denetimi yapması, tek bir veri parçası için dahi gönderilen bu verinin üzerinde hiçbir değişiklik, ekleme, yeniden düzenleme yapılmadığını garanti etmesi, izinsiz kişi ya da uygulamaların erişmemeleri gereken kaynaklara erişemeyecekleri garantisi vermesi beklenir. Bir başka deyişle kriptografi, okunabilir durumdaki bir bilginin istenmeyen taraflarca okunamayacak bir hale dönüştürülmesinde kullanılan tekniklerin tümüdür. Kriptografi ve alt dalları hakkında ayrıntılı bilgi için Nisan 2008 sayımızdaki "Şifrelerin Büyülü Dünyası" adlı makalemize göz atmanızı öneririm.
Kriptografik Bir Program Yazmanın Önkoşulları
Kriptografi ve güvenlik, yazılım dünyasında gün geçtikçe ortaya çıkan yeni teknolojiler sayesinde gittikçe derinleşen konulardır. Modern kriptolama ve güvenlik teknolojileri gelişmiş algoritmaları sayesinde yazılım güvenliğini ön planda tutma amacını güderken, şifreleme işlemi sırasında kaybedilecek zamanı minimum düzeye indirerek etkinlik sağlar. Bu yüzden bir güvenlik programı veya kimlik denetimi yapan kriptografik bir uygulamayı yazmaya başlamadan önce modern kriptolama teknolojileri ve kriptolama algoritmaları araştırılarak kriptolama tekniklerinin sınıflandırılması, varsa aralarındaki ilişkinin kurulması, farklılıklarının veya benzerliklerinin ortaya çıkarılması önkoşullar olarak söylenebilir. Eğer ki bu programlar Java programlama dili kullanılarak geliştirilecekse tavsiyem Java’nın crypto ve security kütüphanelerinin incelenmesidir. Özellikle kriptolama algoritmaları içerisindeki elemanların nitelik ve değerlerine ulaşmak amacıyla crypto paketindeki gerekli bölümler (Cipher, SecretKey, KeyGenerator, PBEKeySpec, SecretKeyFactory, PBEParameterSpec, SecretKeySpec, NoSuchPaddingException, BadPaddingException, IllegalBlockSizeException) ile security paketindeki gerekli bölümlerin (KeySpec, AlgorithmParameterSpec, NoSuchAlgorithmException, InvalidAlgorithmParameterException, InvalidKeyException, InvalidKeySpecException) incelenmesini öneririm.
Enine Boyuna Modern Kriptolama Teknolojileri ve Algoritmaları
Modern kriptografi iki ana dala ayrılır. Bunlar, gizli anahtarlı şifreleme diğer bir deyişle simetrik-anahtar kriptografisi (symmetric-key cryptography) ve asimetrik-anahtar kriptografisi (asymmetric-key cryptography) olarak da bilinen _açık anahtarlı şifreleme_dir. Aşağıda kısaca tanımlamalarını yaptıktan sonra algoritmalarını tek tek ele alacağımız bu kriptosistemler hakkında detaylı bilgiye yine "Şifrelerin Büyülü Dünyası" makalemizden ulaşabilirsiniz. Gizli anahtarlı şifreleme, hem şifreleme hem de şifre çözme işlemleri için aynı anahtarı kullanan bir kripto sistemdir. Senkronize halde çalışan birimler arasında kurulan kripto sistemlerde iletişimin daha kuvvetli olması gerektiğinden bu tip alanlarda simetrik-anahtar kriptografisini kullanmak su götürmez bir gerçektir. Gizli anahtarlı şifreleme aşağıda derinlemesine ele alacağım DES (Data Encryption Standard), Blowfish, DESede ve Pass Phrase gibi yaygın ve güçlü şifreleme algoritmalarına sahiptir. Açık anahtarlı şifrelemede ise haberleşen tarafların her birinde birer çift anahtar bulunur ve bu anahtar çiftlerini oluşturan anahtarlardan biri gizli diğeri de açık anahtardır. Açık anahtarla, bilgiler sadece gizli anahtarın sahibi tarafından çözülebilecek şekilde şifrelenebilir ya da gizli anahtar sahibinin sayısal imzasının ve kimliğinin doğruluğu kontrol edilebilir. Açık anahtarlı şifreleme aşağıda da değineceğim DH (Diffie-Hellman), RSA ve DSA (Digital Signature Algorithm) gibi şifreleme algoritmalarına sahiptir. Sizler de açık ve gizli anahtarlı şifreleme algoritmaları üzerine bir araştırma yapacak olursanız şayet, algoritmaların şifreleyici mekanizmalarını belirli bir anahtar yaratarak bu anahtar yardımıyla kurduğunu gözlemleyeceksiniz. Ayrıca yaratılan anahtarların uzunluklarının ve her kullanım için özel olup olmamalarının, algoritmaların değişkenlik gösteren nitelikleri olduğunu göreceksiniz. Aynı algoritmanın birbirinden farklı uzunlukta veya nitelikte olan anahtarlarından oluşmuş şifreleyicilerle kriptoladığı verilerin farklılık gösterdiğine şahit olacaksınız.
Şimdi yukarıda örneklerini verdiğim algoritmaları daha yakından ele alalım:
DES (Data Encryption Standard):
DES, 64-bit blok büyüklüğüne ve anahtar uzunluğuna sahip fakat sahip olduğu bu 64-bit anahtar uzunluğunun yalnız 56-bit’inin işlevsellik taşıdığı bir öbek şifreleyicidir. Her kullanımında o kullanıma özel yeni bir anahtar yaratması DES’in güçlü, günümüz teknolojisi için algoritmasının yavaş ve 56-bit’lik efektif anahtar uzunluğunun yetersiz kalması DES’in zayıf yönleridir.
DES’i araştırırken bir başka algoritma daha dikkatimi çekti. DES altyapılı olan AES’in (Advanced Encryption Standard), şu an dünyada en yaygın olarak kullanılan simetrik şifreleme algoritması ve Amerikan yönetimi tarafından şifreleme standardı olarak kabul edilmiş bir öbek şifreleyici olduğunu öğrendim. AES’in DES’in aksine donanımda ve yazılımda hızlı olması, daha kolay uygulanabilir olması ve çok daha az hafızaya gerek duyması güçlü yönleri olarak söylenebilir. AES, 128-bit (16 byte) blok büyüklüğüne ve 128, 192 ve 256-bit gibi değişken anahtar uzunluğuna sahip bir algoritmadır.
Blowfish:
Blowfish, DES’in eksik kalmaya başlamasından sonra onun yerini alması amacıyla tasarlanmış bir öbek şifreleyici olup DES gibi 64-bit blok büyüklüğüne sahiptir ve anahtarlarının uzunluğu 32-bit’ten 448 bit’e (56 bayt) kadar uzanır. Blowfish’in en büyük özelliği herkes tarafından dilenildiği şekilde ve ücretsiz olarak kullanılabilir olmak olsa da tüm alt anahtarları oluşturması için 521 kez çalışması gerekiyor – bunun sonucunda yaklaşık 4 KB veri işlenmiş oluyor. Blowfish’in, 4 KB RAM’dan biraz fazla hafıza gereksinimi onun smartcard’lar (akıllı kartlar) gibi en küçük gömülü sistemlerde kullanımını engeller. Yinede yüksek şifreleme oranıyla (high encryption rate), kısa öbek büyüklüğüyle ve e-posta gibi rutin kullanıcı uygulamaları konusundaki etkinliğiyle başarılı bir algoritma olarak değerlendirilmektedir.
Pass Phrase:
Pass Phrase, ATM kartlarının PIN ve smartcard uygulamaları için kullanılan parolalardan farklı olarak kullanıcıdan uzak güvenlik sistemleri için uygulanan, parola mantığında bulunmayan karakterler arasında boşluk bırakmaya olanak tanıyan diğer bir deyişle kullanıcı tarafından kolayca akılda tutulabilecek karakter dizilerini anahtar yaratmada kullanan bir öbek şifreleyicidir. Dizi değişmediği sürece oluşturulacak her anahtar birbirinin aynısı olacaktır. Güvenlik açısından parolalara göre daha esnek ve güvenilir olması Pass Phrase’in güçlü tarafıdır.
DESede:
DESede de yakın akrabası DES gibi her kullanımında o kullanıma özel yeni bir anahtar yaratan fakat yine günümüz teknolojisi için algoritmasının yavaş kalmasıyla kullanılırlığını kaybetmeye başlamış bir öbek şifreleyicidir. 168-bit’lik anahtar uzunluğu onu DES’ten ayıran en önemli özelliği de olsa DESede sahip olduğu bu 168-bit’lik anahtar uzunluğunun yalnız 112-bit’ini efektif olarak kullanır.
DH (Diffie-Hellman):
Açık anahtarlı şifreleme algoritmalarından DH, iki katılımcının öncesinde herhangi bir bilgi alışverişi yapmadan güvenli olmayan bir kanal vasıtasıyla (güvenli bir şekilde) ortak bir şifrede karar kılmalarına yarayan bir protokoldür. Algoritmanın asıl amacı, iki kullanıcının bir anahtarı güvenli bir şekilde birbirlerine iletmeleri ve daha sonrasında da bu anahtar yardımı ile şifreli mesajları birbirlerine gönderebilmelerini sağlamaktır. Algoritma anahtar değişimi ile sınırlıdır olmasına rağmen yinede birçok ticari uygulama bu anahtar değişimini kullanmıştır.
RSA:
RSA ise, hem mesaj şifreleme hem de elektronik imza amacıyla kullanılan daha çok ticari uygulamalarda tercih edilen tam sayılar üzerinde en iyileştirme yapılarak (integer factorization) oluşturulan değerlerden anahtarların üretildiği bir şifreleme teknolojisidir.
DSA:
Son olarak DSA ise anahtar oluşumunda logaritmik fonksiyonları kullanan, internet üzerinden güvenli iletişimi sağlayan TLS (transport layer security) kriptografik protokolü için sağladığı PFS (perfect forward secrecy) desteğiyle tanınan bir algoritmadır. Diğer bir deyişle, PFS temel olarak anahtarlardan birinin gelecekte tehlikeye girmesi durumunda diğer anahtarları güvence altına alan bir özelliktir.
Sonuç olarak asimetrik şifreleme sistemlerinin anahtar oluşumunda karmaşık matematiksel metotlar kullanmaları, onları simetrik şifreleme sistemlerine göre çok daha yavaş olmalarının başlıca sebebidir. Kullanım alanlarının simetrik şifreleme sistemlerine göre daha sınırlı olması ve uygulamada daha yavaş çalışmaları etkin olarak kullanılmamaları sonucunu doğurur. Yapılarının daha çok sunucu – kullanıcı ilişkili sistemlere ve mesaj doğrulama sistemlerine uygun olması, anahtar üretimi ve şifreleme işlemlerinin uzun sürmesi zayıf kalan yönleridir.
Son olarak da DES kriptolama algoritmasını Java programlama dilini kullanarak yazmış olduğum bir program üzerinde göstermek istiyorum. Yazmış olduğum bu program DES algoritmasını kullanarak verilen karakter dizilerini şifrelemeye yada şifrelenmiş bir dizinin şifresini çözmeye yarıyor.
import java.io.UnsupportedEncodingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
public class DesEncrypter {
Cipher eCipher;
Cipher dCipher;
DesEncrypter(SecretKey key) {
try {
eCipher = Cipher.getInstance("DES");
dCipher = Cipher.getInstance("DES");
eCipher.init(Cipher.ENCRYPT_MODE, key);
dCipher.init(Cipher.DECRYPT_MODE, key);
} catch (javax.crypto.NoSuchPaddingException e) {
} catch (java.security.NoSuchAlgorithmException e) {
} catch (java.security.InvalidKeyException e) {
}
}
public String encrypt(String str) {
try {
byte[] utf8 = str.getBytes("UTF8");
// Şifreleme
byte[] enc = eCipher.doFinal(utf8);
// Bytes dizisini BASE64 ile karakter dizisine çevir
return new sun.misc.BASE64Encoder().encode(enc);
} catch (javax.crypto.BadPaddingException e) {
} catch (IllegalBlockSizeException e) {
} catch (UnsupportedEncodingException e) {
} catch (java.io.IOException e) {
}
return null;
}
public String decrypt(String str) {
try {
byte[] dec = new sun.misc.BASE64Decoder().decodeBuffer(str);
// Şifreyi çözme
byte[] utf8 = dCipher.doFinal(dec);
return new String(utf8, "UTF8");
} catch (javax.crypto.BadPaddingException e) {
} catch (IllegalBlockSizeException e) {
} catch (UnsupportedEncodingException e) {
} catch (java.io.IOException e) {
}
return null;
}
public static void main(String[] args) {
try {
// Geçici bir anahtar oluştur
SecretKey key = KeyGenerator.getInstance("DES").generateKey();
// Şifreleyecek objeyi yarat
DesEncrypter encrypter = new DesEncrypter(key);
// Şifrele
String encrypted = encrypter.encrypt("E-Bergi Mart sayısı");
System.out.println(encrypted);
// Şifreyi çöz
String decrypted = encrypter.decrypt(encrypted);
System.out.println(decrypted);
} catch (Exception e) {
}
}
}
Programın çıktısı:
sf8ahDHZ2S1/WXQSIJDAR/LJLiujvqpR
E-Bergi Mart sayısı
Bir sonraki yazımda tekrar görüşmek üzere...
Kaynaklar:
- Chan, Patrick. The Java Developers Almanac 1.4 Volume 1: Examples and Quick Reference 4th Edition
- http://en.wikipedia.org/wiki/Cryptography
- http://en.wikipedia.org/wiki/Symmetric_key_cryptography
- http://en.wikipedia.org/wiki/Asymmetric_key_cryptography