Encryption in Android equivalent to php's MCRYPT_RIJNDAEL_256 -
i using below php code encryption:
$enc_request = base64_encode( mcrypt_encrypt(mcrypt_rijndael_256, $this->_app_key, json_encode($request_params), mcrypt_mode_ecb) );
now trying encrypt in android , getting different encrypted string. below android code:
public void enc(){ byte[] rawkey = getrawkey("my_key".getbytes()); secretkeyspec skeyspec = new secretkeyspec(rawkey, "aes"); cipher cipher = cipher.getinstance("aes"); cipher.init(cipher.encrypt_mode, skeyspec); byte[] encrypted = cipher.dofinal("my_message".getbytes()); string result=base64.encodetostring(encrypted, base64.default); } private static byte[] getrawkey(byte[] seed) throws exception { keygenerator kgen = keygenerator.getinstance("aes"); securerandom sr = securerandom.getinstance("sha1prng"); sr.setseed(seed); kgen.init(256, sr); secretkey skey = kgen.generatekey(); byte[] raw = skey.getencoded(); return raw; }
could 1 me, wrong? , same correct encrypted string in android too.
i've created main
method in java using bouncy castle show inner workings of mcrypt_encrypt()
used in code sample.
this show other developers php's mcrypt_encrypt()
dangerous method use. won't fail much, because rather continues should have stopped long ago. instance, adds or removes values key. emits warning when this, won't directly show in code.
public static void main(string[] args) throws datalengthexception, illegalstateexception, invalidciphertextexception { // constants boolean encrypt = true; boolean decrypt = false; // key either in binary in php or string (dynamic isn't it?), lets assume ascii byte[] givenkey = args[0].getbytes(charset.forname("ascii")); // determine key size dynamically, thought idea... // note: php emit warning if key size larger, use // largest key size otherwise final int keysize; if (givenkey.length <= 128 / byte.size) { keysize = 128; } else if (givenkey.length <= 192 / byte.size) { keysize = 192; } else { keysize = 256; } // create 256 bit key adding 0 bytes decoded key byte[] keydata = new byte[keysize / byte.size]; system.arraycopy(givenkey, 0, keydata, 0, math.min(givenkey.length, keydata.length)); keyparameter key = new keyparameter(keydata); // create rijndael cipher 256 bit block size, not aes blockcipher rijndael = new rijndaelengine(256); // use padding method works on data cannot end 0 valued bytes zerobytepadding c = new zerobytepadding(); // use ecb mode encryption, should never used paddedbufferedblockcipher pbbc = new paddedbufferedblockcipher(rijndael, c); // initialize cipher using key (no need iv, ecb) pbbc.init(encrypt, key); // create plain text byte array byte[] plaintext = args[1].getbytes(charset.forname("utf8")); // create buffer ciphertext byte[] ciphertext = new byte[pbbc.getoutputsize(plaintext.length)]; int offset = 0; offset += pbbc.processbytes(plaintext, 0, plaintext.length, ciphertext, offset); offset += pbbc.dofinal(ciphertext, offset); // show ciphertext system.out.println(new string(hex.encode(ciphertext), charset.forname("ascii"))); // reverse encryption pbbc.init(decrypt, key); byte[] decrypted = new byte[pbbc.getoutputsize(ciphertext.length)]; offset = 0; offset += pbbc.processbytes(ciphertext, 0, ciphertext.length, decrypted, offset); offset += pbbc.dofinal(decrypted, offset); // print out correctly, isn't correct system.out.println(new string(decrypted, charset.forname("utf8"))); // check out zero's @ end system.out.println(new string(hex.encode(decrypted), charset.forname("utf8"))); // lets make bit shorter... php way // note in php, string may *not* contain null terminator // add before printing string system.out.println(new string(decrypted, charset.forname("utf8")).replaceall("\\x00+$", "")); }
warning: above code contains zerobytepadding
. later discovered there difference between bouncy castle , php in respect: bouncy castle expects have pad, while php doesn't. bouncy adds 1..n bytes while php adds 0..(n-1) bytes, n block size (32 bytes rijndael-256/256). may have padding/unpadding yourself; sure test edge cases!
Comments
Post a Comment