JCE, Sifrelemeler ve Hatalar

Yer yer projelerde, özellikle başka sistemlerle entegre oluyorsanız, sizden bazı bilgileri şifrelenmiş olarak göndermenizi bekleyeceklerdir. Her ne kadar gördüğüm çoğu uygulamada güvenlik önlemi alınmasa da güvenlik önemlerini alan uygulamalarda var. İşte bu tip bir uygulama ile entegre olmanız gerekiyorsa sizden bazı bilgileri şifrelenmiş olarak göndermenizi isteyeceklerdir. Bu yazımda bu şifrelemeyi nasıl yapabileceğinizden, piyasada çok kullanılan alternatiflerinden ve alabileceğiniz hataları nasıl çözebileceğinizden bahsedeceğim.

JCE ve Alternatifleri

JCE yani Java Cryptography Extension, javanın şifreleme API’nın adı. Her API’da olduğu gibi bunu kullanmak zorunda değilsiniz. Başka bir provider da kullanabilirsiniz. Bu alternatiflerin başında ise BouncyCastle ismindeki kütüphane geliyor. Şifreleme yapmanız gereken bir uygulama yazdığınızda, uygulamanız JCE ile konuşur. JCE ise arka tarafta kendisine atanmış olan kütüphaneyi kullanarak sizin için şifreleme yapar.

AES, DES ve Digerleri

Piyasada en çok karşınıza çıkacak olan şifreleme algoritmaları AES ve DES’tir. Şimdi AES ve DES’in ne olduğuna, ve JCE ile bunları nasıl uygulayabileceğinize bakalım.

AES

AES, Advanced Encryption Standard, simetrik anahtar tipindeki şifreleme metodudur. Simetrik anahtar demek, hem şifrelerken hem de şifreyi çözerken aynı anahtarın kullanıldığı anlamına gelir. Temel olarak 128, 196 ve 256 bitlik anahtarları destekler. Tahmin edeceğiniz üzere anahtar boyutumuz arttıkça güvenliğimiz de artacaktır. Tabi anahtarın saklanması ile ilgili güvenlik başka bir konu. Aynı şekilde algoritmanın nasıl çalıştığına da girmeyeceğim. Burada güvenlik açısından bilinmesi gereken AES, DES’in halefidir.

JCE ile AES

Şimdi JCE ile AES şifrelemesinin nasıl yapılacağına bakalım. Bu arada şunu belirteyim, AES sadece tek bir yöntemle yapılmıyor. Bu sebepten ne yaptığınızı nasıl yaptığınızı bilmenizi öneririm. Biz aşağıdaki örnekte sade bir şekilde AES kullanacağız. Ama AES kullanarak aynı input için her defasında farklı bir çıktı almakta mümkün. Bunun için Initialization Vector adı verilen yapılar kullanılıyor. Git deposunda bunun için örnekler bulabilirsiniz.

DES

DES, Data Encryption Standart, AES gelene kadar en popüler simetrik şifreleme metoduydu. Sonrasında populerliği kalmadı. Ama hala eski projelerde karşınıza çıkabilir. Bu sebepten hala kullanıldığını söylesem yanlış birşey söylemiş olmam. Temel olarak 64 bitlik (56 + 8 parrity) anahtarlar kullanır. Blok olarak 64 bitlik bloklar kullanır ki AES 128 bitlik bloklar kullanmaktadır.

JCE ile DES

Şimdi ise JCE ile DES şifrelemesinin nasıl yapılacağına bakalım. AES’te olduğu gibi DES kullanırkende detaya girmeyeceğim. Sade bir şekilde nasıl DES kullanılacağına bakacağım.

Sık Alınan Hatalar

Anahtar Boyunun Fazla Uzun Olması

Javada çeşitli nedenlerden dolayı anahtar uzunluğu 128 bite sabitlenmiştir. Bunun üzerinde bir anahtar boyu kullanırsanız hata mesajı alırsınız. Fakat bildiğiniz üzere AES 256 anahtar boyutunuda destekliyor. Daha yüksek boyutta bir anahtar kullanırsanız aşağıdaki hata ile karşılaşmanız olasıdır.

Caused by: java.security.InvalidKeyException: Illegal key size
at javax.crypto.Cipher.checkCryptoPerm(Cipher.java:1024)
at javax.crypto.Cipher.implInit(Cipher.java:790)
at javax.crypto.Cipher.chooseProvider(Cipher.java:849)
at javax.crypto.Cipher.init(Cipher.java:1348)
at javax.crypto.Cipher.init(Cipher.java:1282)
at com.bahadirakin.cipher.SymetricCipher.initCipher(SymetricCipher.java:53)
… 28 more

Zaten aşağıdakine benzer bir kod parçası çalıştırdığınızda, sistemin izin verdiği maximum anahtar sözcük uzunluğunu öğrenebilirsiniz.

System.out.println(“Max Allowed Key Length: ” + Cipher.getMaxAllowedKeyLength(“AES”));

Bunun üstesinden gelmek için öncelikle Java SE indirdiğiniz adrese gidip “Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy Files” dosyalarını indirmek.

Örneğin Java SE 7 kullanıyorsanız bu adresten ilgili dosyaları indirebilirsiniz.

Şimdi JRE üzerinde bazı dosyaları değiştireceğiz. Bunu yapmadan önce yedek almakta fayda var. Bu sebepten $JAVA_HOME\jre\lib\security klasörü altındaki US_export_policy.jar ve local_policy.jar dosyalarını yedekleyin.

Daha sonra indirdiğiniz Zip dosyasını açın ve içerisindeki US_export_policy.jar ve local_policy.jar dosyalarını $JAVA_HOME\jre\lib\security kalsörü altına kopyalayın. Tekrar uygulamanızı başlattığınızda sorununuz çözülmüş olacak.

Init Vektör ve Mod Uyumsuzlugu

Biz az önceki örnekte basitçe DES ve AES ile nasıl şifreleme yapıldığını gördük. Fakat yer yer İnit vektör kullanmanız gerekebilir. İnit vektör genelde bir sonucun iki kere üretilmesini önlemek amacı ile kullanılır. Her çalışma modunda kullanmanıza gerek yoktur ama bazı çalışma modları ,örneğin CBC gibi, İnit Vektör kullanımını zorunlu kılar. Eğer init vektör kullanmazsanız, aşağıdakine benzer bir hata ile karşılaşırsınız.

Caused by: java.security.InvalidKeyException: Parameters missing
at com.sun.crypto.provider.CipherCore.init(CipherCore.java:388)
at com.sun.crypto.provider.AESCipher.engineInit(AESCipher.java:186)
at javax.crypto.Cipher.init(Cipher.java:1210)
at javax.crypto.Cipher.init(Cipher.java:1153)
at com.bahadirakin.cipher.SymetricCipher.initCipher(SymetricCipher.java:49)
… 28 more

Burada init vektör sağladığınızda sorununuz düzelecektir. Eğer elinizde init vektör yoksa aşağıdaki kod parçasını kullanarak default bir tane üretebilirsiniz.

Son

Her ne kadar projelerin çoğunda uzak doğulu kardeşlerimizin yazdığı AESUtils kullanılsa da umarım neyin ne için kullanıldığına netlik kazandırabilmişimdir. AESUtils kullanırken encoding kısmına ve kullanılan Key’in şifrelenmiş olduğuna dikkat etmenizi öneriyorum. Haberleşmelerinizde sorun çıkartabilir.

Kaynaklar

Git

End Of Line