password
(A char[]
) ve salt
(a byte[]
—8 bayt tarafından bir SecureRandom
marka tarafından seçilen ve gizli tutulması gerekmeyen iyi bir tuz yapar) bant dışı alıcıyla paylaşın . Sonra bu bilgilerden iyi bir anahtar elde etmek için:
/* Derive the key, given password and salt. */
SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA256");
KeySpec spec = new PBEKeySpec(password, salt, 65536, 256);
SecretKey tmp = factory.generateSecret(spec);
SecretKey secret = new SecretKeySpec(tmp.getEncoded(), "AES");
Sihirli sayılar (bir yerlerde sabitler olarak tanımlanabilir) 65536 ve 256 sırasıyla anahtar türev yineleme sayısı ve anahtar boyutudur.
Anahtar türetme işlevi, önemli hesaplama çabaları gerektirecek şekilde yinelenir ve bu, saldırganların birçok farklı şifreyi hızlı bir şekilde denemelerini önler. Yineleme sayısı, mevcut bilgi işlem kaynaklarına bağlı olarak değiştirilebilir.
Anahtar boyutu 128 bite kadar azaltılabilir, bu da yine de "güçlü" şifreleme olarak kabul edilir, ancak AES'yi zayıflatan saldırılar tespit edilirse, bir güvenlik payı vermez.
Uygun bir blok zincirleme modu ile kullanıldığında, aynı türetilmiş anahtar birçok mesajı şifrelemek için kullanılabilir. Olarak şifre bloğu zinciri (CBC) , rastgele bir başlatma vektörü (IV) 'düz metin aynı olsa bile, farklı bir şifre metin, sonuçta her mesaj için oluşturulur. CBC kullanabileceğiniz en güvenli mod olmayabilir (aşağıdaki AEAD'a bakın); farklı güvenlik özelliklerine sahip başka birçok mod vardır, ancak hepsi benzer rastgele bir giriş kullanır. Her durumda, her şifreleme işleminin çıktıları şifre metni ve başlatma vektörüdür:
/* Encrypt the message. */
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, secret);
AlgorithmParameters params = cipher.getParameters();
byte[] iv = params.getParameterSpec(IvParameterSpec.class).getIV();
byte[] ciphertext = cipher.doFinal("Hello, World!".getBytes("UTF-8"));
Mağaza ciphertext
ve iv
. Şifre çözme işleminde, SecretKey
aynı tuz ve yineleme parametreleriyle parola kullanılarak tam olarak aynı şekilde yeniden oluşturulur. Şifreyi bu tuşla ve mesajla birlikte verilen başlatma vektörünü başlatın :
/* Decrypt the message, given derived key and initialization vector. */
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.DECRYPT_MODE, secret, new IvParameterSpec(iv));
String plaintext = new String(cipher.doFinal(ciphertext), "UTF-8");
System.out.println(plaintext);
Java 7 , AEAD şifreleme modları için API desteği içeriyor ve OpenJDK ve Oracle dağıtımlarına dahil olan "SunJCE" sağlayıcısı, Java 8 ile başlayarak bunları uyguluyor. CBC yerine bu modlardan biri şiddetle önerilir; verilerin bütünlüğünü ve gizliliğini koruyacaktır.
java.security.InvalidKeyException
"Geçersiz anahtar boyutu veya varsayılan parametreler" mesajıyla A , şifreleme gücünün sınırlı olduğu anlamına gelir ; sınırsız güç yetkisi ilke dosyaları doğru konumda değil. Bir JDK'da,${jdk}/jre/lib/security
Sorun açıklamasına bağlı olarak, ilke dosyaları doğru yüklenmemiş gibi görünüyor. Sistemlerin birden fazla Java çalışma zamanı olabilir; doğru konumun kullanıldığından emin olmak için iki kez kontrol edin.