Bu yanıtta, "Basit Java AES şifreleme / şifre çözme örneği" ana temasına yaklaşmayı seçiyorum, özel hata ayıklama sorusuna değil çünkü bunun okuyucuların çoğuna fayda sağlayacağını düşünüyorum.
Bu, Java'da AES şifreleme hakkındaki blog yazımın basit bir özetidir, bu yüzden herhangi bir şey uygulamadan önce onu okumanızı tavsiye ederim. Bununla birlikte, yine de kullanmak için basit bir örnek sunacağım ve nelere dikkat edileceğine dair bazı ipuçları vereceğim.
Bu örnekte , Galois / Counter Mode veya GCM modu ile kimliği doğrulanmış şifreleme kullanmayı seçeceğim . Bunun nedeni, çoğu durumda gizlilikle birlikte bütünlük ve özgünlük istemenizdir ( blogda daha fazlasını okuyun ).
AES-GCM Şifreleme / Şifre Çözme Eğitimi
Java Cryptography Architecture (JCA) ile AES-GCM ile şifreleme / şifre çözme için gerekli adımlar aşağıda verilmiştir . Diğer örneklerle karıştırmayın farklılıklar kodunuzu tamamen güvensiz hale getirebileceğinden .
1. Anahtar Oluşturun
Kullanım durumunuza bağlı olduğu için, en basit durumu kabul edeceğim: rastgele bir gizli anahtar.
SecureRandom secureRandom = new SecureRandom();
byte[] key = new byte[16];
secureRandom.nextBytes(key);
SecretKey secretKey = SecretKeySpec(key, "AES");
Önemli:
2. Başlatma Vektörünü Oluşturun
Aynı gizli anahtarın farklı şifre metinleri oluşturması için bir başlatma vektörü (IV) kullanılır .
byte[] iv = new byte[12]; //NEVER REUSE THIS IV WITH SAME KEY
secureRandom.nextBytes(iv);
Önemli:
3. IV ve Anahtar ile şifreleyin
final Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");
GCMParameterSpec parameterSpec = new GCMParameterSpec(128, iv); //128 bit auth tag length
cipher.init(Cipher.ENCRYPT_MODE, secretKey, parameterSpec);
byte[] cipherText = cipher.doFinal(plainText);
Önemli:
- 16 bayt / 128 bit kimlik doğrulama etiketi kullan (bütünlüğü / özgünlüğü doğrulamak için kullanılır)
- kimlik doğrulama etiketi otomatik olarak şifre metnine eklenecektir (JCA uygulamasında)
- GCM bir akış şifresi gibi davrandığından, herhangi bir dolgu gerekmez
- kullanım
CipherInputStream
büyük veri yığınlarını şifrelerken
- değiştirilmişse ek (gizli olmayan) verilerin kontrol edilmesini ister misiniz? Buradaki Diğer ile ilişkili verileri kullanmak isteyebilirsiniz
cipher.updateAAD(associatedData);
.
3. Tek Mesaja Seri Hale Getirin
Sadece IV ve şifreli metni ekleyin. Yukarıda belirtildiği gibi, IV'ün gizli olmasına gerek yoktur.
ByteBuffer byteBuffer = ByteBuffer.allocate(iv.length + cipherText.length);
byteBuffer.put(iv);
byteBuffer.put(cipherText);
byte[] cipherMessage = byteBuffer.array();
Bir dize gösterimine ihtiyacınız varsa isteğe bağlı olarak Base64 ile kodlayın . Ya Android'in ya da Java 8'in yerleşik uygulamasını kullanın (Apache Commons Codec'i kullanmayın - bu çok kötü bir uygulama). Kodlama, bayt dizilerini ASCII güvenli hale getirmek için dize gösterimine "dönüştürmek" için kullanılır, örneğin:
String base64CipherMessage = Base64.getEncoder().encodeToString(cipherMessage);
4. Şifre Çözmeyi Hazırlayın: Seriyi Kaldır
Mesajı kodladıysanız, önce onu bayt dizisi olarak çözün:
byte[] cipherMessage = Base64.getDecoder().decode(base64CipherMessage)
Önemli:
5. Şifresini çöz
Şifreyi başlatın ve şifreleme ile aynı parametreleri ayarlayın:
final Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");
//use first 12 bytes for iv
AlgorithmParameterSpec gcmIv = new GCMParameterSpec(128, cipherMessage, 0, 12);
cipher.init(Cipher.DECRYPT_MODE, secretKey, gcmIv);
//use everything from 12 bytes on as ciphertext
byte[] plainText = cipher.doFinal(cipherMessage, 12, cipherMessage.length - 12);
Önemli:
- eklemeyi unutmayın ilişkili verileri ile
cipher.updateAAD(associatedData);
şifreleme sırasında eklenirse.
Bu özetin içinde çalışan bir kod parçacığı bulunabilir.
En son Android (SDK 21+) ve Java (7+) uygulamalarının AES-GCM'ye sahip olması gerektiğini unutmayın. Daha eski sürümler eksik olabilir. Yine de bu modu seçiyorum, çünkü benzer Mac'ten Şifrele moduna (örneğin AES-CBC + HMAC ile ) kıyasla daha verimli olmasının yanı sıra uygulanması daha kolay . AES-CBC'nin HMAC ile nasıl uygulanacağına ilişkin bu makaleye bakın .