java - BadPaddingException when decrypting AES with the same key -
this tester:
public class cryptographysimpletests extends activitytestcase { public void testscryptographyclass_encryptanddecrypt() { final string orgval = "hi world! :d"; final string key = "key"; try { final byte[] encryptkey = cryptography.deriveaes256key(key); final byte[] decryptkey = cryptography.deriveaes256key(key); //deviation method assert.asserttrue(arrays.equals(encryptkey, decryptkey)); byte[] encrypted = cryptography.encryptaes(encryptkey, orgval.getbytes()); assert.assertfalse(arrays.equals(encrypted, orgval.getbytes())); byte[] decrypted = cryptography.decryptaes(decryptkey, encrypted); assert.asserttrue(arrays.equals(orgval.getbytes(), decrypted)); } catch (exception e) { assert.fail(e.getmessage()); } } }
wich fails because of last assert:
assert.fail(e.getmessage());
when trying execute:
byte[] decrypted = cryptography.decryptaes(decryptkey, encrypted);
gives stack trace:
javax.crypto.badpaddingexception: error:06065064:digital envelope routines:evp_decryptfinal_ex:bad decrypt @ com.android.org.conscrypt.nativecrypto.evp_cipherfinal_ex(native method) @ com.android.org.conscrypt.opensslcipher.dofinalinternal(opensslcipher.java:430) @ com.android.org.conscrypt.opensslcipher.enginedofinal(opensslcipher.java:466) @ javax.crypto.cipher.dofinal(cipher.java:1340) @ bdevel.encuentralo.utils.cryptography.decryptaes(cryptography.java:59) @ bdevel.encuentralo.cryptographysimpletests.testscryptographyclass_encryptanddecrypt(cryptographysimpletests.java:32) @ java.lang.reflect.method.invoke(native method) @ java.lang.reflect.method.invoke(method.java:372) @ android.test.instrumentationtestcase.runmethod(instrumentationtestcase.java:214) @ android.test.instrumentationtestcase.runtest(instrumentationtestcase.java:199) @ junit.framework.testcase.runbare(testcase.java:134) @ junit.framework.testresult$1.protect(testresult.java:115) @ junit.framework.testresult.runprotected(testresult.java:133) @ junit.framework.testresult.run(testresult.java:118) @ junit.framework.testcase.run(testcase.java:124) @ android.test.androidtestrunner.runtest(androidtestrunner.java:191) @ android.test.androidtestrunner.runtest(androidtestrunner.java:176) @ android.test.instrumentationtestrunner.onstart(instrumentationtestrunner.java:555) @ android.app.instrumentation$instrumentationthread.run(instrumentation.java:1837)
these functions:
public class cryptography { /** * @param key aes key * @param inputvalue data encrypt * @return can return null if goes wrong */ public static byte[] encryptaes(byte[] key, byte[] inputvalue) throws nosuchpaddingexception, badpaddingexception, illegalblocksizeexception { secretkeyspec skeys = new secretkeyspec(key, "aes"); cipher cipher = null; try { cipher = cipher.getinstance("aes/cbc/pkcs5padding"); cipher.init(cipher.encrypt_mode, skeys); } catch (nosuchalgorithmexception | invalidkeyexception i) { cipher = null; } return cipher != null ? cipher.dofinal(inputvalue) : null; } public static byte[] decryptaes(byte[] key, byte[] encrypteddata) throws nosuchpaddingexception, badpaddingexception, illegalblocksizeexception { secretkeyspec skeys = new secretkeyspec(key, "aes"); cipher cipher = null; try { cipher = cipher.getinstance("aes/cbc/pkcs5padding"); cipher.init(cipher.decrypt_mode, skeys); } catch (nosuchalgorithmexception | invalidkeyexception i) { cipher = null; } return cipher != null ? cipher.dofinal(encrypteddata) : null; } private static byte[] deriveaes256keysalt = null; public static byte[] deriveaes256key(string password) throws invalidkeyspecexception, nosuchalgorithmexception { /* store these things on disk used derive key later: */ int iterationcount = 1000; int saltlength = 32; // bytes; should same size output (256 / 8 = 32) int keylength = 256; // 256-bits aes-256, 128-bits aes-128, etc /* when first creating key, obtain salt this: */ if(deriveaes256keysalt == null) { securerandom random = new securerandom(); deriveaes256keysalt = new byte[saltlength]; random.nextbytes(deriveaes256keysalt); } /* use derive key password: */ keyspec keyspec = new pbekeyspec(password.tochararray(), deriveaes256keysalt, iterationcount, keylength); secretkeyfactory keyfactory = secretkeyfactory.getinstance("pbkdf2withhmacsha1"); byte[] keybytes = keyfactory.generatesecret(keyspec).getencoded(); return keybytes; } }
if assert checks if keys same works, why exception ?
you eating java.security.invalidkeyexception: illegal key size or default parameters
exception in encryptaes
, decryptaes
methods. don't eat them, either declare throws
or promote runtimeexception
.
turns out have 2 problems, for reason, can't 256, 128 solves that, requesting cbc
without ivparameterspec
(which causing java.security.invalidkeyexception: parameters missing
). supply or change ecb
:
public static byte[] encryptaes(byte[] key, byte[] inputvalue) throws nosuchpaddingexception, badpaddingexception, illegalblocksizeexception, nosuchalgorithmexception, invalidkeyexception { secretkeyspec skeys = new secretkeyspec(key, "aes"); cipher cipher = cipher.getinstance("aes/ecb/pkcs5padding"); cipher.init(cipher.encrypt_mode, skeys); return cipher.dofinal(inputvalue); } public static byte[] decryptaes(byte[] key, byte[] encrypteddata) throws nosuchpaddingexception, badpaddingexception, illegalblocksizeexception, nosuchalgorithmexception, invalidkeyexception { secretkeyspec skeys = new secretkeyspec(key, "aes"); cipher cipher = cipher.getinstance("aes/ecb/pkcs5padding"); cipher.init(cipher.decrypt_mode, skeys); return cipher.dofinal(encrypteddata); }
key length:
public static byte[] deriveaes256key(string password) throws invalidkeyspecexception, nosuchalgorithmexception { ... int keylength = 128; // 256-bits aes-256, 128-bits aes ...
so got working that, step 1 stop eating exception , you'll better clues , work out on own.
Comments
Post a Comment