24 Nisan 2019 Çarşamba

JCA Cipher Sınıfı - Simetrik ve Asimetrik Şifreleme İçindir

Giriş
Şu satırı dahil ederiz.
import javax.crypto.Cipher;
Kullanım
1. getInstance() metodu ile istenilen algoritmaı gerçekleştiren Cipher nesnesi elde edilir
2. Simetrik şifreleme için SecretKey ile başlatılır. Şöyle yaparız
KeyGenerator keyGenerator = KeyGenerator.getInstance("AES");
keyGenerator.init(new SecureRandom());
SecretKey secretKey = keyGenerator.generateKey();

// Initialize the Cipher for Encryption
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.ENCRYPT_MODE, secretKey);
Şifreleme için doFinal metod çağrılır. Şöyle yaparız
String str = ...;
byte[] encryptedData = cipher.doFinal(str.getBytes());
Açma için  şöyle yaparız
SecretKey secretKey = ...;

byte[] encryptedData = ...;
        
cipher.init(Cipher.DECRYPT_MODE, secretKey);
byte[] decryptedData = cipher.doFinal(encryptedData);
getInstance metodu
DES
Şöyle yaparız.
Cipher desCipher = Cipher.getInstance("DES");
Şöyle yaparız
Cipher pbeCipher = Cipher.getInstance("PBEWithMD5AndDES");
3DES
Şöyle yaparız.
Cipher cipher = Cipher.getInstance("PBEWithSHA1AndDESede");
AES
AES yazısına taşıdım.

RSA
Şöyle yaparız
Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
Şöyle yaparız.
Cipher cipher = Cipher.getInstance("RSA/ECB/OAEPWithSHA1AndMGF1Padding"); 
SecretKey
SecretKey ile şöyle elde etmek için şöyle yaparız.
SecretKey key = ...;
Cipher cipher = Cipher.getInstance(key.getAlgorithm());
init metodu - encrypt
Key nesnesi alır. Simetrik şifreleme için Key arayüzünden kalıtan SecretKey nesnesi kullanılır.
Örnek
Şöyle yaparız.
SecretKey key = ...;
cipher.init(Cipher.ENCRYPT_MODE, key);
Örnek
Asimetrik şifreleme için Key arayüzünden kalıtan PublicKey nesnesi kullanılır. Şöyle yaparız.
RSAPublicKey eServer = (RSAPublicKey) cert.getPublicKey();
cipher.init(Cipher.ENCRYPT_MODE, eServer);
init metodu - encrypt
Key + AlgorithmParameters nesnesi alır.
Örnek
Şöyle yaparız.
SecretKey secretKey = ...
PBEParameterSpec pbeParameterSpec = ...
cipher.init(Cipher.ENCRYPT_MODE, secretKey, pbeParameterSpec);
init metodu - decrypt
Key nesnesi alır.
Örnek
Şifreyi açmak için şöyle yaparız.
SecretKey myDesKey = ...;
cipher.init(Cipher.DECRYPT_MODE, myDesKey);
x.509 sertifikası için şöyle yapabiliriz.
PrivateKey key = ...;
cipher.init(Cipher.DECRYPT_MODE, key);
init metodu - decrypt
Key + AlgorithmParameters nesnesi alır.
Örnek
İstenirse salt verilebilir.
byte[] salt = ...;
cipher.init(Cipher.DECRYPT_MODE, key, new PBEParameterSpec(salt, 20));
Örnek
Salt şöyle de verilebilir.
byte[] salt = {...};
int iterationCount = 2;
AlgorithmParameterSpec paramSpec = new PBEParameterSpec(salt, iterationCount);

cipher.init(Cipher.DECRYPT_MODE, key, paramSpec);
Örnek
AES ile spec kullanılıyor.
IvParameterSpec ivspec = ...;
SecretKeySpec keyspec = ...;
Cipher cipher = ...;
cipher.init(Cipher.ENCRYPT_MODE, keyspec, ivspec);
doFinal metodu - encrypt
init metodu ile nesnenin nasıl ilklendirildiğine bağlı olarak belirtilen byte'ları şifreler veya açar. Şifrelemek için şöyle yaparız.
byte[] text = ...;
byte[] textEncrypted = desCipher.doFinal(text);
doFinal metodu - decrypt
Açma için şöyle yaparız.
byte[] textEncrypted = ...;
byte[] textDecrypted = desCipher.doFinal(textEncrypted);

23 Nisan 2019 Salı

ServiceLoader Sınıfı - Service Provider Interface (SPI) İçindir

Giriş
Açıklaması şöyle
There are four important components in the Java SPI:

Service interface: An interface or abstract class that defines the methods of the class contract that the service provider implements.

Service Implementation: The implementation class that provides the service.

SPI configuration file: The filename must exist in the META-INF/services directory. The file name should be the same as the service provider interface fully qualified name. Each line in the file has an implementing service class detail, which is the fully qualified name of the service provider class.

ServiceLoader: Java SPI key class, used to load the service of the service provider interface. There are various utility methods in ServiceLoader for getting specific implementations, iterating over them, or reloading the service again.

Kullanım
1. Service interface java.sql.Driver olsun
2. META-INF/services/java.sql.Driver" isimli bir dosya yaratırız. Bu dosya SPI configuration file. Bu dosyaya Driver arayüzünü gerçekleştiren sınıfların tam yolunu yazarız
3. ServiceLoader ile gerçekleştirimleri yükleriz.

- Bu sınıf bulduğu nesneleri kendi içinde saklar. Dolayısıyla aynı nesneyi tekrar elde etmek için
singleton gibi kullanılması gerekiyor.

Kötü Tarafı - Anti Pattern
Açıklaması şöyle.
If an object uses a service locator to get its dependencies, your test framework will also need a service locator.
iterate metodu
Şöyle yaparız.
Iterator<IService> services = ServiceLoader.load(IService.class).iterator();
while (services.hasNext()) {
  IService service = services.next();
  ...
}
load metodu
Örnek
Şöyle yaparız.
ServiceLoader loader = ServiceLoader.load(Operation.class);
Örnek
Elimizde şöyle bir arayüz olsun
public interface Compresser {
  byte[] compress(byte[] bytes);
  byte[] decompress(byte[] bytes);
}
Şöyle bir dosya yaratırız
META-INF/services
Dosyanın içi şöyledir
cn.omgzui.demoserver.serviceproviders.GzipCompresser
cn.omgzui.demoserver.serviceproviders.ZipCompresser
Şöyle yaparız
ServiceLoader<Compresser> serviceLoader = ServiceLoader.load(Compresser.class);
for (Compresser service : serviceLoader) {
  ...
}


17 Nisan 2019 Çarşamba

AtomicInteger Sınıfı

Giriş
Şu satırı dahil ederiz.
import java.util.concurrent.atomic.AtomicInteger;
Kullanım amacı şöyle.
There are two main uses of AtomicInteger:
  1. As an atomic counter (incrementAndGet(), etc) that can be used by many threads concurrently
  2. As a primitive that supports compare-and-swap instruction (compareAndSet()) to implement non-blocking algorithms.
CAS Algoritması
Açıklaması şöyle.
The entire java.util.concurrent.atomic package in Java is based around the notion of compareAndSet(). This method uses machine-level locking to set a value only if the current value matches the expected precondition. The compareAndSet() method returns a Boolean, True if the "set" operation succeeded; or, False if the "set" operation failed the precondition. As such, this method can be executed inside a loop that will continuously try running the compareAndSet() operation until is succeeds.
constructor
Şöyle kullanırız
AtomicInteger  counter = new AtomicInteger(0);
compareAndSet metodu
İmzası şöyle. Parametreler currentValue, newValue olarak ta düşünülebilir. Nesnenin değeri ile currentValue aynı ise yani değişiklik yok ise yeni değer atanır. Bu işlem başarılı ise true döner. Başarısız ise false döner. Bu metodu genellikle döngü içinde kullanmak gerekir.
public final boolean compareAndSet(int expect, int update);
accumulateAndGet metodu - int x, IntBinaryOperator accumulatorFunction
Açıklaması şöyle
Atomically applies the specified accumulator function to the current value and the x value. Returns the updated value after the accumulation.
Örnek
Şöyle yaparız
// Define an accumulator function that multiplies the current value by the operand
IntBinaryOperator accumulator = (currentValue, operand) -> currentValue * operand;

// Using accumulateAndGet to multiply the current value by 3
int updatedValue = atomicInt.accumulateAndGet(3, accumulator);
System.out.println("Updated Value: " + updatedValue);

addAndGet metodu - int delta
Açıklaması şöyle
Atomically adds the specified delta to the current value and returns the updated value.
Örnek
Şöyle yaparız
AtomicInteger i = new AtomicInteger(8);
while ((i.addAndGet(-3)) > 0) ;
System.out.println("i = " + i.intValue());
decrementAndGet metodu
Açıklaması şöyle
Atomically decrements the current value by 1 and returns the updated value.
getAndAdd metodu
Açıklaması şöyle
Atomically decrements the current value by 1 and returns the previous value.
Değişkeni belirtilen değer kadar artırır ve eski değeri döner. Döngüyü kendi içinde kurar. Metodun içi şöyle
public final int getAndAddInt(Object var1, long var2, int var4) {
  int var5;
  do {
    var5 = this.getIntVolatile(var1, var2);
  } while(!this.compareAndSwapInt(var1, var2, var5, var5 + var4));

  return var5;
}
getAndAdd metodu - int delta
Açıklaması şöyle
Atomically adds the specified delta to the current value and returns the previous value.
getAndAccumulate metodu - int x + IntBinaryOperator accumulatorFunction
Açıklaması şöyle
Atomically applies the specified accumulator function to the current value and the x value. Returns the previous value before the accumulation.
Örnek
Şöyle yaparız
// Define an accumulator function that multiplies the current value by the operand
IntBinaryOperator accumulator = (currentValue, operand) -> currentValue * operand;

// Using getAndAccumulate to multiply the current value by 5
int previousValue = atomicInt.getAndAccumulate(5, accumulator);
System.out.println("Previous Value: " + previousValue);
System.out.println("Updated Value: " + atomicInt.get());

getAndDecrement metodu
Açıklaması şöyle
Atomically decrements the current value by 1 and returns the previous value.
getAndIncrement metodu
Açıklaması şöyle
Atomically increments the current value by 1 and returns the previous value.
Değişkeni artırır ve eski değeri döner. Döngüyü kendi içinde kurar. Metodun içi şöyle.
public final int getAndIncrement() {
  for (;;) {
    int current = get();
    int next = current + 1;
    if (compareAndSet(current, next))
      return current;
  }
 }
getAndAdd metodu
Değişkeni beliritlen değer kadar artırır ve eski değeri döner. Döngüyü kendi içinde kurar. Metodun içi şöyle
public final int getAndAddInt(Object var1, long var2, int var4) {
  int var5;
  do {
    var5 = this.getIntVolatile(var1, var2);
  } while(!this.compareAndSwapInt(var1, var2, var5, var5 + var4));

  return var5;
}
getAndSet metodu
Yeni değer atayıp eski değeri döner. Metodun için şöyle.
public final boolean getAndSet(boolean newValue) {
  for (;;) {
    boolean current = get();
    if (compareAndSet(current, newValue))
      return current;
  }
}
incrementAndGet metodu
Değişkeni artırır sonra yeni değeri döndürür. Açıklaması şöyle
Atomically increments the current value by 1 and returns the updated value.
Örnek
Şöyle yaparız.
counter.incrementAndGet() ;
set metodu
İmzası şöyle.
public final void set(int newValue);
updateAndGet metodu
İmzaları şöyle
int updateAndGet(IntUnaryOperator updateFunction)
int getAndUpdate(IntUnaryOperator updateFunction)
Örnek
[1- 59] arasında sayı için şöyle yaparız
AtomicInteger counter = new AtomicInteger();

public int getNextValue() {
    return counter.updateAndGet(n -> (n >= 60) ? 1 : n + 1);
}
Örnek
[1- 9] arasında sayı için şöyle yaparız
AtomicInteger counter = new AtomicInteger(0);

// to get & update
counter.getAndUpdate(value -> (value + 1) % 10)