java - Sending Strings Encoded by a secret key over TCP stream BadPaddingException with Windows -


i think i'm having problem specific windows operating system (windows 7) using writeutf() , readutf() methods sending encrypted strings on tcp connection.

the client , server first establish connection using private-public key pair. agree on shared key used further communications. problem occurs when strings encrypted shared key , sent via writeutf() , readutf() have bad padding. first instance when occurs when encrypted acknowledgement server client using writeutf() method sent.

the problem occurs sometimes! program runs smoothly through completion no errors, other times badpaddingexception thrown stating "given final block not padded" @ both client side:

            byte[] bytedecriptedack = decryptcipher.dofinal(encryptedack.getbytes()); 

and server side:

            byte[] bytedecriptedack = decryptcipher.dofinal(encryptedpassword.getbytes()); 

the problem not occur when running code on osx operating system. therefore, believe has how windows represents utf strings, writes utf strings or reads utf strings.

i'm @ loss trying fix problem. appreciated.

thanks

the code establishing connection client side:

private void establishconnection() {     try {         int numbytespubkey = in.readint();         byte[] bytespubkey = new byte[numbytespubkey];         in.readfully(bytespubkey, 0, numbytespubkey);          //get public key server         x509encodedkeyspec pubkeyspec = new x509encodedkeyspec(bytespubkey);         keyfactory keyfactory = keyfactory.getinstance("rsa");         publickey pubkey = keyfactory.generatepublic(pubkeyspec);          //generate secret key communicating         keygenerator keygen = keygenerator.getinstance("aes");         keygen.init(128); //key size         secretkey secretkey = keygen.generatekey();         byte[] encodedsecretkey = secretkey.getencoded();          //use public key encode message containing secret key send server         encryptcipher = cipher.getinstance("rsa");         encryptcipher.init(cipher.encrypt_mode, pubkey);         byte[] cipherdata = encryptcipher.dofinal(encodedsecretkey);          //send secret key server encoded servers public key         out.writeint(cipherdata.length);         out.write(cipherdata, 0, cipherdata.length);          //read acknowledge server         secretkeyspec secretkeyspec = new secretkeyspec(encodedsecretkey,"aes");          string encryptedack = in.readutf();         decryptcipher = cipher.getinstance("aes");         decryptcipher.init(cipher.decrypt_mode, secretkeyspec);         byte[] bytedecriptedack = decryptcipher.dofinal(encryptedack.getbytes());          if(!(new string(bytedecriptedack).equals("ack"))) {             system.err.println("server acknowledgement corrupted. terminate communications.");             system.exit(1);         }          //send password server          encryptcipher = cipher.getinstance("aes");         encryptcipher.init(cipher.encrypt_mode, secretkeyspec);         byte[] cipheredpassword = encryptcipher.dofinal("password".getbytes());         out.writeutf(new string(cipheredpassword));      } catch (exception e) {         system.err.println(e.getmessage());         e.printstacktrace();     } } 

the code establishing connection server side:

private void establishconnection() {     try {         //generate public/private key pair communicating         keypairgenerator keygen = keypairgenerator.getinstance("rsa");         securerandom random = securerandom.getinstance("sha1prng", "sun");         keygen.initialize(1024, random);          keypair pair = keygen.generatekeypair();         privatekey privkey = pair.getprivate();         publickey pubkey = pair.getpublic();          //send public key client         byte[] bytespubkey = pubkey.getencoded();         out.writeint(bytespubkey.length);         out.write(bytespubkey, 0, bytespubkey.length);          //read in secret key use further communications         int numbytessecretkey = in.readint();         byte[] bytessecretkey = new byte[numbytessecretkey];         in.readfully(bytessecretkey, 0, numbytessecretkey);          decryptcipher = cipher.getinstance("rsa");         decryptcipher.init(cipher.decrypt_mode, privkey, decryptcipher.getparameters());         byte[] bytedecriptedsecretkey = decryptcipher.dofinal(bytessecretkey);         secretkeyspec secretkeyspec = new secretkeyspec(bytedecriptedsecretkey,"aes");          //send acknowledgment encoded secret key: ack         encryptcipher = cipher.getinstance("aes");         encryptcipher.init(cipher.encrypt_mode, secretkeyspec);         byte[] cipheredack = encryptcipher.dofinal("ack".getbytes());          out.writeutf(new string(cipheredack));          //read password client         string encryptedpassword = in.readutf();         decryptcipher = cipher.getinstance("aes");         decryptcipher.init(cipher.decrypt_mode, secretkeyspec);         byte[] bytedecriptedack = decryptcipher.dofinal(encryptedpassword.getbytes());          if(!(new string(bytedecriptedack).equals("password"))) {             system.err.println("access denied. client password incorrect. terminate communications.");             system.exit(1);         } else {             system.err.println("access granted.");         }      } catch (exception e) {         e.printstacktrace();     } }  

byte[] cipheredack = encryptcipher.dofinal("ack".getbytes()); out.writeutf(new string(cipheredack)); 

that's not going work. utf , string character data. have raw bytes here, cannot interpreted text.

send them binary data:

out.write(cipheredack); 

the reason see difference between os x , windows did not specify character encoding when coercing bytes string, becomes platform-specific. if character data, you'd pass character set constructor make platform-independent. in case, not character data anyway, go bytes.

also, why don't use ssl?


Comments

Popular posts from this blog

blackberry 10 - how to add multiple markers on the google map just by url? -

php - guestbook returning database data to flash -

delphi - Dynamic file type icon -