@Override
  public void run() {
    byte[] line = null;
    byte[] bytes = null;

    // TODO Auto-generated method stub
    System.out.println("Welcome new users, ID: " + id + '\n');
    ip = clientHandler.getClientIPAddress();
    // read client public key
    line = clientHandler.readBytes();
    if (!(new String(Arrays.copyOfRange(line, 0, 4))).startsWith("key")) {
      clientHandler.sendMessage("authentication:false");
      return;
    } else {
      clientPublicKey = Arrays.copyOfRange(line, 4, line.length);
    }
    encrypt = new EncryptDatabase(clientPublicKey, Server.privateKey);
    // send random number
    bytes = encrypt.getEncryptedMessage(int2byte(nounce++));
    clientHandler.sendBytes(bytes);
    line = clientHandler.readBytes();
    byte[] decipher = (new DecryptDataBase(clientPublicKey, Server.privateKey, line)).decrypt();
    int r = (new BigInteger(decipher)).intValue();
    if (r != nounce) {
      System.out.println("nounce auth failed: \n" + r);
      System.out.println();
      return;
    }
    // read auth info.
    line = clientHandler.readBytes();
    line = decryptWithNounce(line);
    String head = new String(Arrays.copyOfRange(line, 0, line.length - 32));
    byte[] hashcode = Arrays.copyOfRange(line, line.length - 32, line.length);
    System.out.println("Client id: " + id + ":  " + head);
    if (head.startsWith("authentication")) {
      if (this.authUser(head, hashcode, clientPublicKey)) {
        byte[] AuthTrue = "authentication:true".getBytes();
        System.out.println("\nauthentication:true");
        sendWithEncryptNounce(AuthTrue);
      } else {
        byte[] AuthFalse = "authentication:false".getBytes();
        System.out.println("\nauthentication:frue");
        sendWithEncryptNounce(AuthFalse);
        this.terminate();
        return;
      }
    } else {
      System.out.println("Client didn't start with authentication, gonna drop connection. " + line);
      clientHandler.sendMessage("Please authenticate yourself");
      this.terminate();
      return;
    }
    // send on line users -> ip key
    this.sendClientUserIP();
    this.sendClientUserTICKET(clientPublicKey);
    this.terminate();
  }
 private void sendWithEncryptNounce(byte[] message) {
   byte[] bytes = combineBytes(int2byte(nounce++), message);
   bytes = encrypt.getEncryptedMessage(bytes);
   clientHandler.sendBytes(bytes);
 }