java - Working with JPasswordField and handling the password with getPassword + server login procedure -


after day of long programming want post useful else.

few days ago wondering how handle jpasswordfield's method getpassword() correct procedure pass value server , answer.

and question:

how can correctly value jpasswordfield in safe way , handle create login procedure server?

this solution reached.

first of decided procedure of login safe enough purpose, didn't want send plain password server , didn't want store plain password (obviously) in database.

the first thing way secure password is never ever exchanged on network in plain , readable form, because of possible "man in middle", in few words reading messages in way server.

the password need hashed, means transformed quite long sequence of hexadecimal characters. thing of hash is (hopefully) one-way. can't de-hash password.

there many algorithms this, choose sha256.

the password hashed, between us, can not enough. if hacker able steal hash there techniques can bring him successful "translation" of it. add variable in equation, , make life harder, can add salt password prior hash it. salt piece of string added in position desire password. avoids kind of attacks based on dictionary , used password.

but if hacker better trained me can't read password, how can i?

the answer simple, don't have to.

but understand need jump moment in "registration procedure" moment when new user added database. it:

  1. the client ask server registered sending nickname.
  2. the server answer token salt password.
  3. the client salt password, hash , send server.
  4. the server receive unreadable there's no security problem, , store nickname , salt. salted hashed password "common secret".

so login procedure this:

  1. the client ask server login
  2. the server answer salt
  3. the client salts password hashes , sends server.
  4. the server compare shared secret received string. if equals user allowed login.

this should quite fine, in case if hacker knows shared secret can access server without problem because doing changed password, not readable, still usable directly.

to avoid behavior have add passage in our chain:

  1. the client ask server login
  2. the server answers salt , random session-salt
  3. the client salts password, hashes it. @ point salts again hash , re-hash it. send hashed-salted-hash-of-salted-password server
  4. the server takes shared secret, salts random session salt , hashes it. if 2 strings equals user allowed login.

now procedure clear have issue solve. if handle kind of string can persist in memory long time, if put password in string can readable in plain form long time. not us, not first think it, java indeed created way avoid password persisting. solution use array of characters. because if array persisting in memory, datas spread no order in memory , difficult re-create original password.

re inventing hot water? yep, use getpassword() method in jpasswordfield.

but quite difficult newbie. char[] array, , strange not expert.

the first thing reach our mind can transform array in plain string ....... want avoid. need handle array as-is.

we need method salt , hash password, result can this:

public static string digestsalted(string salt, char[] password) throws nosuchalgorithmexception {     messagedigest md = messagedigest.getinstance("sha-256");      arraylist<byte> list = new arraylist<byte>();     (int = 0; < password.length; i++) {         //string ch = string.valueof(password[i]);         //byte[] b = ch.getbytes();         //for (int j = 0; j < b.length; j++) {         //  list.add(b[j]);         //}                     list.add((byte)password[i]);     }     byte[] saltinbytes = salt.getbytes();     byte[] tobehashed = new byte[(saltinbytes.length + list.size())];     (int = 0; < saltinbytes.length; i++) {         tobehashed[i] = saltinbytes[i];     }     (int = saltinbytes.length; < list.size() + saltinbytes.length; i++) {         tobehashed[i] = list.get(i - saltinbytes.length);     }      md.update(tobehashed);      byte bytedata[] = md.digest();      stringbuffer hexstring = new stringbuffer();     (int = 0; < bytedata.length; i++) {         string hex = integer.tohexstring(0xff & bytedata[i]);         if (hex.length() == 1) {             hexstring.append('0');         }         hexstring.append(hex);     }     return hexstring.tostring();  } 

this method create array of bytes passing through many little strings append salt. once salted hash result sha256.

now return can string because hashed , there no problem of security.

this give solution first part of question.

the second part implements our protocol between server , client.

i show code in client significant enough understand procedure. using blocking queue messages put when read socket. code:

public void login(string nickname, char[] password) {     if (cl == null) {         throw new runtimeexception();     }     long s = sys.gettime();     cl.send("nick " + nickname);     incomingmessage reply = null;     try {         reply = this.mh.getmessage(); //the response nick msg         if (reply.getcommand().equalsignorecase("login")) {             arraylist<string> params = reply.getparams();             string accountsalt = params.get(0);             string randomsalt = params.get(1);             try {                 string sharedsecret = shahash.digestsalted(accountsalt, password);                 string saltedsharedsecret = shahash.digestsalted(randomsalt, sharedsecret);                 if (saltedsharedsecret != null) {                     cl.send("pass " + saltedsharedsecret);                     reply = this.mh.getmessage();                     if (reply.getcommand().equalsignorecase("welcome") && reply.getparams().get(0).equals(nickname)) {                         // ************ log ************ //                         log.config("logged in.");                         // ***************************** //                         this.running = true;                         this.loggedin = true;                         mh.startexecutor();                         log.config("time passed: " + (sys.gettime() - s));                         mh.startgame();                     } else {                         // ************ log ************ //                         log.warning("a problem has occured while trying login server.");                         // ***************************** //                         joptionpane.showmessagedialog(null, "error while logging server, shutting down.\n- error 006 -");                         system.exit(0);                     }                 }             } catch (nosuchalgorithmexception e) {                 // ************ log ************ //                 log.warning("error while sha hashing password, shutting down.");                 // ***************************** //                 joptionpane.showmessagedialog(null, "error while sha hashing password, shutting down.\n- error 005 -");                 system.exit(0);             }         }     } catch (interruptedexception e) {         e.printstacktrace();     } } 

the code, have clear how protocol works, it's easy understand thing should considered this.mh.getmessage() blocking method, means thread wait until available in queue before trying it.

this (almost) how solved problem. let me know if there error in answer or if need clarification. hope useful someone. have nice programming


Comments

Popular posts from this blog

Unable to remove the www from url on https using .htaccess -