30 Mayıs 2017 Salı

PBEKeySpec Sınıfı

Giriş
Şu satırı dahil ederiz.
import java.security.spec.KeySpec;
import javax.crypto.spec.PBEKeySpec;
Açıklaması şöyle
In general cryptographic hashes such as MD5, SHA-1 or SHA-512 should not be used to directly hash a password. A password hash or PBKDF should be used. Examples are PBKDF2, bcrypt, scrypt and Argon2. These functions also take a salt and work factor to provide additional protection.
Cryptographic hash algoritmalarını direkt kullanmanın zararı ile ilgili bir diğer açıklama ise şöyle
The length of the password is limited by the length of the cypher() encryption algorithm. For instance, AES128 takes a 16-byte key. That means that your scheme couldn't accept passwords longer than 16 bytes, if we used AES128 encryption as cypher(). That's generally a bad idea -- artificial restrictions on the length of the password can only harm security.
Açıklaması şöyle. Bu sınıf AES gibi symmetric şifrelemelerde kullanılıyor.
Password hash algorithms have been invented for safe password hashing, also known as password based key derivation functions (PBKDF). The difference between a password hash and a PBKDF is mainly how the result is used: directly as a password hash to compare with a stored password hash or as symmetric key for input in a symmetric cipher or MAC algorithm.

Well known password hash algorithms are PBKDF2, bcrypt, scrypt and of course the already mentioned Argon2. The latter two also contain options for configuring memory hardness, to overcome hardware based attacks.
Bu sınıf altta SHA-1 kullanıyor. Açıklaması şöyle
The functions can often be configured using a hash function. For instance PBKDF2 requires a secure hash as configuration parameter, and it (kinda) defaults to SHA-1.
Kullanım
PBKDF2 (Password-Based Key Derivation Function 2) algoritmasını gerçekleştirir. Şöyle yaparız.
SecretKeyFactory f = SecretKeyFactory.getInstance("...");
byte[] key = f.generateSecret(spec).getEncoded();
constructor - password + salt + iterationCount
Şöyle yaparız.
byte[] salt = { ... };
String passPhrase = ...;
int iterationCount = 2;
KeySpec spec = new PBEKeySpec(passPhrase.toCharArray(), salt, iterationCount);
constructor - password + salt + iterationCount + keyLength
AES için şöyle yaparız.
PBEKeySpec spec = new PBEKeySpec("password", "salt".getBytes(),1000  , 128);

Covariant Return Type

Giriş
Covariant Return Type virtual bir metod A tipini döndürüyorsa, bu metodu yeniden gerçekleştiren bir alt sınıf A'dan kalıtan B tipini döndürebilir anlamına gelir.

Java Covariant Return Type özelliğini desktekler. Bu özelliklik Java 1.5 ile geldi.
Örnek
Doğru bir örnek şöyle
public class Parent{  
  public Object doSomething(){}  
 }  
 public class Child extends Parent{  
  public String doSomething() {}  
 }
Örnek
Hatalı bir örnek şöyle
public interface Exemplary
{
  CharSequence getText();
}

public class Example implements Exemplary
{
  @Override
  public String getText(); // legal
}

public class BadExample implements Exemplary
{
  @Override
  public Integer getText(); // error
}
Örnek
Arayüz için şöyle yaparız. Elimizde bir arayüz olsun.
public interface SuperInterface {

  SuperInterface getSomething();
}
Bu arayüzden kalıtan  ve farklı bir nesne dönen covariant arayüz için şöyle yaparız.
public interface SubInterface extends SuperInterface {

  SubInterface getSomething();
}



29 Mayıs 2017 Pazartesi

DriverManager Sınıfı

Giriş
Şu satırı dahil ederiz.
import java.sql.DriverManager;
Bu sınıf DataSource ile aynı işi görür. Yeni kodlarda DriverManager yerine DataSource arayüzünden kalıtan sınıfları kullanmak lazım.

registerDriver metodu - eski kodlarda

1.1 JDBC 4'ten sonra
Artık Class.ForName()'i çağırmaya gerek yok. JVM driver'ı otomatik olarak yüklüyor.

1.2  JDBC 4'ten önce
Eğer jar dosyası CLASSPATH içinde yoksa şöyle bir exception atar.
java.sql.SQLException:
No suitable driver found for jdbc:mysql://localhost:3306/mydb
SQL Server şöyle bir hata fırlatır.
java.lang.ClassNotFoundException: com/microsoft/jdbc/sqlserver/SQLServerDriver
Şöyle yaparız.
DriverManager.registerDriver (new oracle.jdbc.OracleDriver());
Bir çok kodda registerDriver çağrısı yerine Class.forName () çağrısı yapılır. Bu çağrı kendi içinde registerDriver işlemini yerine getirir.

Yani şöyle yapmaya gerek yok.
Driver d = (Driver)Class.forName("...").newInstance());
DriverManager.registerDriver (d);
Access
Şöyle yaparız.
Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
MySQL
Şöyle yaparız.
Class.forName("com.mysql.jdbc.Driver");
Oracle
odbc*.jar dosyasının classpath içinde olması gerekir. * karakteri yerine bir sayı gelir. Örneğin ojdbc6.jar şeklinde olabilir. Oracle sitesinde bir sürü jar mevcut. Bunların farkları şöyle
  • ojdbc*.jar - all the classes to support basic functionality for the Thin and OCI drivers
  • ojdbc*_g.jar - same as ojdbc*.jar except compiled with the -g option to include debugging information and with java.util.logging calls included.
  • ojdbc*dms.jar - same as ojdbc*.jar except includes code to support Oracle Dynamic Monitoring Service (DMS). Also includes some JDBC logging support. This file can only be used when dms.jar is also in the classpath. The dms.jar file is not shipped as part of the RDBMS product. It is only available as part of the Oracle Application Server product.
  • ojdbc*dms_g.jar - same as ojdbc*dms.jar except compiled with the -g option to include debugging information and with full JDBC logging support.
  • orai18n.jar - contains the configuration information to support all Oracle character sets in Advanced Data Types (objects). If the database character set is one other than UCS2,ASCII, ISO_LATIN_1, UTF8 and AL32UTF8 and the application uses ADTs, then you must include this file in your classpath.
Şöyle yaparız.
Class.forName("oracle.jdbc.driver.OracleDriver");
Bu kod çalışınca OracleDriver içindeki statik kod kendisini DriverManager sınıfına ekler. Çünkü OracleDriver içindeki static constructor şuna benzer
public class OracleDriver { 
  static {
    DriverManager.registerDriver(new OracleDriver());
  }
}
PostgreSQL
Şöyle yaparız.
Class.forName("org.postgresql.Driver");
SQLite
Şöyle yaparız.
Class.forName("org.sqlite.JDBC"); 
SQLServer
Şöyle yaparız.
Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");
getConnection metodu - url

PostgreSQL
Şöyle yaparız.
String url = "jdbc:postgresql://localhost:5435/mydbname?user=..."&pass=...";
Connection con = DriverManager.getConnection (url);
SQLite
Windows'ta şöyle yaparız.
Connection con = DriverManager.getConnection("jdbc:sqlite:‪C:\\database.db");
Linux'ta şöyle yaparız
Connection con = DriverManager.getConnection("jdbc:sqlite:/"+ myDBpath);
SQL Server
Şöyle yaparız.
String url = "jdbc:sqlserver://localhost:1433;databaseName=CaiMaster";
Connection conn = DriverManager.getConnection(url);
Şöyle yaparız.
java.sql.Connection conn = ;
DriverManager.getConnection("jdbc:sqlserver://localhost; integratedSecurity=true;
 databaseName=baessland; user=sa; password=1234;");
getConnection metodu - url + Properties
Örnek ver.

getConnection metodu - url + user + password
Metoda geçilen url'lerin hepsi "jdbc:" ile başlamalı. Bu metodun 3 tane overload edilmiş hali var. İlkinde kullanıcı adı ve şifresi url'nin bir parçası olarak verilir. İkinciside iseurl haricinde parametreler olarak geçilir.

Access
64 bit Java uygulamalarında şöyle yaparız. Test.accdb dosyasına bağlanılır.
String url = "jdbc:odbc:DRIVER={Microsoft Access Driver (*.mdb, *.accdb)};DBQ="+
"C:\\Test.accdb;";
Connection con = DriverManager.getConnection (url, "", "");
32 bit Java uygulamalarında şöyle yaparız. Db.mdb dosyasına bağlanılır.
String url = "jdbc:odbc:Driver={Microsoft Access Driver (*.mdb)};DBQ=Db.mdb";
Connection con = DriverManager.getConnection (url,"","");
Apache Derby
Şöyle yaparız.
String url = "jdbc:derby://localhost:1527/Quet";
String usname = "eenas";
String pass= "2234";
Connection con = DriverManager.getConnection (url, usname, pass);
MySQL
POM'da şu satır olmalıdır.
<!--Mysql-Connector-->
<dependency>
  <groupId>mysql</groupId>
  <artifactId>mysql-connector-java</artifactId>
  <version>5.1.36</version>
</dependency>
Bağlantı string'inin şekli şöyledir.
"jdbc:mysql://hostname:portNo/databaseName";
Şöyle yaparız.
String url = "jdbc:mysql://localhost:3306/mydb";
String usname = "root";
String pass = "mysql";

Connection con =DriverManager.getConnection (url, usname, pass);
İstersek IP de verebiliriz.
String url ="jdbc:mysql://192.168.1.2:3306/mydb";
Bağlantı string'i bazı parametreler alabilir.

MySQL autoReconnect
Şöyle yaparız.
"jdbc:mysql://localhost:3306/mydb?autoReconnect=true"
MySQL connectTimeout
Şöyle yaparız.
"jdbc:mysql://localhost:3306/mydb?connectTimeout=15000"
MySQL characterEncoding
Veritabanı sunucusu UTF-8 değilse bağlantıyı UTF-8 olacak hale getirebiliriz. Şöyle yaparız.
"jdbc:mysql://localhost:3306/mydb?characterEncoding=UTF-8"
MySQL useUnicode + characterEncoding
Şöyle yaparız.
"jdbc:mysql://localhost:3306/mydb?useUnicode=true&characterEncoding=UTF-8"
MySQL useLegacyDatetimeCode ve serverTimezone
Şöyle yaparız.
"jdbc:mysql://localhost/mydb?useLegacyDatetimeCode=false&
serverTimezone=UTC+05:30";
Şöyle yaparız.
"jdbc:mysql://localhost:3306/restapi?useUnicode=true&
useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&
serverTimezone=UTC";
Oracle
URL için şeklen şöyle yaparız.
Connection con =
DriverManager.getConnection ("jdbc:oracle:thin:@<hostname>:<port num>:<DB name>
                    ,"user","password");
Gerçek bir örnek
String url="jdbc:oracle:thin:@JamesPJ-PC:1521:skypark";
String usname="system";
String pass="tiger";
Connection con = DriverManager.getConnection (url,usname,pass);
Bir başka örnek
Connection con = DriverManager.getConnection(
"jdbc:oracle:thin:@localhost:1521:xe","yy","yy"); 
thin olmayan sürücüler için tnsnames.ora dosyası kullanılır.

3. getLoginTimeout ve setLoginTimeout metodları
Bu metodlar ile login işlemine zaman aşımı yapmak mümkün.
// Getting timeout value
int timeout = DriverManager.getLoginTimeout();

// Setting timeout value
DriverManager.setLoginTimeout(timeout)