AES etiketine sahip kayıtlar gösteriliyor. Tüm kayıtları göster
AES etiketine sahip kayıtlar gösteriliyor. Tüm kayıtları göster

2 Ocak 2020 Perşembe

AES/ECB

Örnek
Şöyle yaparız. ECB modunda ilklendirir.
Cipher cipher = Cipher.getInstance("AES");
PKC5Padding
Örnek
Şöyle yaparız
Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");

3 Ocak 2019 Perşembe

AES/CBC

Giriş
- SecretKey arayüzünden kalıtan SecretKeySpec yaratılır.
- Cipher nesnesi yaratılır.

NoPadding
Örnek
Şöyle yaparız. Verinin blok büyüklüğünde olması gerekir.
Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding");
Yoksa açma esnasında şu exception fırlatılır
javax.crypto.BadPaddingException: Given final block not properly padded
PKC5Padding
Örnek
Veriyi gerekiyorsa 8 byte blok olacak şekilde padler. PKC7Padding ise parametriktir ve 1- 255 arasında bir blok büyüklüğüne padleyebilir.

AES 16 byte'lık bloklar halinde çalıştığı için aslında bu kullanım biraz hatalı.

Şöyle yaparız
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
Şifreleme için şöyle yaparız. IV için rastgele byte'lar oluşturulur. Key için kullanılan byte'lar kullanılmaz. Şifreleme yapıldıktan sonra IV + salt + şifreli veri gönderilir.
SecureRandom random = new SecureRandom();
byte[] salt = new byte[16];
random.nextBytes(salt);
// AES-256
KeySpec spec = new PBEKeySpec("password".toCharArray(), salt, 65536, 256);
SecretKeyFactory f = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
byte[] key = f.generateSecret(spec).getEncoded();

byte[] ivBytes = new byte[16];
random.nextBytes(ivBytes);
IvParameterSpec iv = new IvParameterSpec(ivBytes);

Cipher c = Cipher.getInstance("AES/CBC/PKCS5Padding");
c.init(Cipher.ENCRYPT_MODE, key, iv);
byte[] encValue = c.doFinal(valueToEnc.getBytes());

byte[] finalCiphertext = new byte[encValue.length+2*16];
System.arraycopy(ivBytes, 0, finalCiphertext, 0, 16);
System.arraycopy(salt, 0, finalCiphertext, 16, 16);
System.arraycopy(encValue, 0, finalCiphertext, 32, encValue.length);

return finalCiphertext;
Örnek
Aşağıdaki kod yanlış çünkü IV random doldurulmuyor.
private String KEY_PRIVATE_HP = "__hpcSecretKey__";

private IvParameterSpec getIvParameterSpec() {
  byte[] empty = new byte[16];
  return new IvParameterSpec(empty);
}

private String encryptBin(String value) {
  SecretKeySpec secretKeySpec = new SecretKeySpec(KEY_PRIVATE_HP.getBytes("UTF-8"),"AES");
  Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5PADDING");
  cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec, getIvParameterSpec());

  byte[] encrypted = cipher.doFinal(value.getBytes());
  return Base64.encodeToString(encrypted, Base64.NO_WRAP);
}


26 Ocak 2018 Cuma

AES

Kullanım
Her şey Cipher nesnesine dayanır.

1. Cipher.getInstance () ile AES cipher nesnesini yarat

2.Cipher.init() ile cipher nesnesini ilklendir.
2.1 Key
Key bilgisi SecretKeySpec nesnesi ile geçilir. Bazı kodlarda SecretKeySpec nesnesini üretmek için KeyGenerator kullanılıyor. Yani key ürettiriliyor.
KeyGenerator -> SecretKeySpec(SecretKey arayüzünden kalıtır) -> Cipher.init()
Örnek
Elimizde key verisi olsun.
byte[] key = ...;
Şöyle yaparız.
SecretKeySpec skeySpec = new SecretKeySpec(key, "AES");

Bazı kodlarda ise
PBEKeySpec -> SecretKeyFactory -> SecretKey -> Cipher.init() şeklinde yapılıyor.
Örnek
Şöyle yaparız. Aslında SecretKey nesnesi direkte Cipher nesnesine geçilebilir.


int PASSWORD_ITERATIONS = 65536; // vs brute force
int KEY_LENGTH          = 256;

char[]     pass                = "password".toCharArray();
byte[]     salt                = "salt".toCharArray (); 


SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
PBEKeySpec spec = new PBEKeySpec(pass, salt, PASSWORD_ITERATIONS, KEY_LENGTH);

SecretKey secretKey = factory.generateSecret(spec);
SecretKeySpec sKeySpec = new SecretKeySpec(secretKey.getEncoded(), "AES");//Gereksiz ?

2.2 IV
Örnek
Şöyle yaparız. Blok büyüklüğü 16 byte yani 128 bit kabul ediliyor.
SecureRandom sr = new SecureRandom();
byte[] byteIV = new byte[16];
sr.nextBytes(byteIV);

IvParameterSpec IV  = new IvParameterSpec(byteIV);
IV'yi kendimiz sağlarsak şöyle yaparız. 
byte[] initVector = ...;
byte[] secretKey = ...;
Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding");
cipher.init(Cipher.ENCRYPT_MODE new SecretKeySpec(secretKey, "AES"),
  new IvParameterSpec(initVector));
Eğer IV'yi sağlamazsak bir tane IV üretilir. Açıklaması şöyle
If you don't specify an initialisation vector, and one is required with the block mode you're using, then a random IV will be allocated.
Daha sona cipher.getIV() ile IV alınır ve karşı tarafa şifrelenmiş veriden önce gönderilir. Böylece karşı taraf cipher.init (...) çağrısına bu veriyi geçer ve veriyi açabilir.

İlklendirmede AES 256 bit kullanırsak "InvalidKeyException : Illegal key size" hatası alırsak
Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy'i kurmak gerekir.

3. Cipher.doFinal () ile veriyi şifrele.
Bu kısım zaten bilindik :)

AES/ECB
AES/ECB yazısına taşıdım.

AES/CBC
AES/CBC yazısına taşıdım.

AES/CTR
Örnek
Şöyle yaparız.
String CIPHER_ALGORITHM = "AES/CTR/NoPadding";
Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);
AES/GCM
Şöyle yaparız.
Cipher cipher = Cipher.getInstance("AES/GCM/PKCS5Padding");
Java tag çıktısını şifrelenmiş verinin sonuna ekler.