Java Encryption and C# Decryption Issue -
i have dll in c# encrypts , decrypts string texts (something basic), need implement same encryption method in java, applications can encrypt data , send library.
i can't modify c# code, because it's in production, java don't, please, suggestion must done @ java side.
basically i'm trying implement same c# encryption method in java. here c# codes:
note: passphrase, salt, etc. values referential.
const string passphrase = "ihdyhz6bgqys0ff1/1s="; const string saltvalue = "0a0qvv09oxd3gsyhvra="; const string hashalgorithm = "sha1"; const int passworditerations = 3; const string initvector = "gjrlrz6ingnckbqv"; const int keysize = 256; public static string encrypt(string plaintext) { byte[] initvectorbytes = encoding.ascii.getbytes(initvector); byte[] saltvaluebytes = encoding.ascii.getbytes(saltvalue); byte[] plaintextbytes = encoding.utf8.getbytes(plaintext); passwordderivebytes password = new passwordderivebytes( passphrase, saltvaluebytes, hashalgorithm, passworditerations); byte[] keybytes = password.getbytes(keysize / 8); rijndaelmanaged symmetrickey = new rijndaelmanaged(); symmetrickey.mode = ciphermode.cbc; icryptotransform encryptor = symmetrickey.createencryptor( keybytes, initvectorbytes); memorystream memorystream = new memorystream(); cryptostream cryptostream = new cryptostream(memorystream, encryptor, cryptostreammode.write); cryptostream.write(plaintextbytes, 0, plaintextbytes.length); cryptostream.flushfinalblock(); byte[] ciphertextbytes = memorystream.toarray(); memorystream.close(); cryptostream.close(); string ciphertext = convert.tobase64string(ciphertextbytes); return ciphertext; } public static string decrypt(string ciphertext) { byte[] initvectorbytes = encoding.ascii.getbytes(initvector); byte[] saltvaluebytes = encoding.ascii.getbytes(saltvalue); byte[] ciphertextbytes = convert.frombase64string(ciphertext); passwordderivebytes password = new passwordderivebytes( passphrase, saltvaluebytes, hashalgorithm, passworditerations); byte[] keybytes = password.getbytes(keysize / 8); rijndaelmanaged symmetrickey = new rijndaelmanaged(); symmetrickey.mode = ciphermode.cbc; icryptotransform decryptor = symmetrickey.createdecryptor( keybytes, initvectorbytes); memorystream memorystream = new memorystream(ciphertextbytes); cryptostream cryptostream = new cryptostream(memorystream, decryptor, cryptostreammode.read); byte[] plaintextbytes = new byte[ciphertextbytes.length]; int decryptedbytecount = cryptostream.read(plaintextbytes, 0, plaintextbytes.length); memorystream.close(); cryptostream.close(); string plaintext = encoding.utf8.getstring(plaintextbytes, 0, decryptedbytecount); return plaintext; }
here java code, encrypts data, not @ same way c# encryption code, when try decrypt using c# library throws exception: "length of data decrypt invalid"
static final string passphrase = "ihdyhz6bgqys0ff1/1s="; static final string saltvalue = "0a0qvv09oxd3gsyhvra="; static final string hashalgorithm = "sha1"; static final int passworditerations = 3; static final string initvector = "gjrlrz6ingnckbqv"; static final int keysize = 256; public static string encrypt(string plaintext) { char[] password = passphrase.tochararray(); byte[] salt = saltvalue.getbytes(); byte[] iv = initvector.getbytes(); byte[] ciphertext = new byte[0]; secretkeyfactory factory; try { factory = secretkeyfactory.getinstance("pbkdf2withhmacsha1"); keyspec spec = new pbekeyspec(password, salt, passworditerations, 256); secretkey tmp; tmp = factory.generatesecret(spec); secretkey secret = new secretkeyspec(tmp.getencoded(), "aes"); cipher cipher = cipher.getinstance("aes/cbc/pkcs5padding"); cipher.init(cipher.encrypt_mode, secret); algorithmparameters params = cipher.getparameters(); //iv = params.getparameterspec(ivparameterspec.class).getiv(); ciphertext = cipher.dofinal(plaintext.getbytes("utf-8")); } catch (nosuchalgorithmexception e) { // todo auto-generated catch block e.printstacktrace(); } catch (invalidkeyspecexception e) { // todo auto-generated catch block e.printstacktrace(); } catch (nosuchpaddingexception e) { // todo auto-generated catch block e.printstacktrace(); } catch (invalidkeyexception e) { // todo auto-generated catch block e.printstacktrace(); } //catch (invalidparameterspecexception e) { // // todo auto-generated catch block // e.printstacktrace(); //} catch (illegalblocksizeexception e) { // todo auto-generated catch block e.printstacktrace(); } catch (badpaddingexception e) { // todo auto-generated catch block e.printstacktrace(); } catch (unsupportedencodingexception e) { // todo auto-generated catch block e.printstacktrace(); } return base64.encode(new string(ciphertext)); }
edit 1: fixed final byte array conversion string in java code, jon skeet suggested.
this what's wrong, in java code:
return base64.encode(ciphertext.tostring());
you're calling tostring()
on byte array, always give string such [b@3e25a5
.
edit: ooh, noticed can change java side. hooray.
basically, need use base64 api allows:
return base64.encode(ciphertext);
i'm disappointed in base64 apis allow "encode" string, honest... base64 fundamentally encodes binary data text, , decodes text data binary. oh well...
anyway, use this api (the encodebytes
method) if need 1 allows pass in byte array.
i haven't checked on actual encryption part in detail, c# code @ least looks it's doing right thing in terms of encodings. using
statements though :)
Comments
Post a Comment