Android: string encryption with AES 256 bit encryption using iv and secret key

SecureRandom random = new SecureRandom(); // quite heavy, look into a lighter method. String stringToEncrypt = "mypassword"; byte[] realiv = new byte[16]; random.nextBytes(realiv); Cipher ecipher = Cipher.getInstance("AES"); SecureRandom random = new SecureRandom(); // quite heavy, look into a lighter method. byte[] realiv = new byte[16]; random.nextBytes(realiv); byte[] secret = "somelongsecretkey".getBytes(); SecretKeySpec secretKey = new SecretKeySpec(secret, "AES"); ecipher.init(Cipher.ENCRYPT_MODE, secretKey, random); byte[] encryptedData = ecipher.doFinal(); 

but init() accepts only 3 parameters. I need a way to do something like:

 ecipher.init(Cipher.ENCRYPT_MODE, stringToEncrypt, secretKey, random); 
0
source share
2 answers

In the general case, you do not need something that generates random numbers for an algorithm that has deterministic behavior. Also, you don’t need IV when you use ECB block mode, and this is what the default is for Java. To be precise, Java defaults to "AES/ECB/PKCS5Padding" for Cipher.getInstance("AES") .

So you should be fine with this code:

 // lets use the actual key value instead of the platform specific character decoding byte[] secret = Hex.decodeHex("25d6c7fe35b9979a161f2136cd13b0ff".toCharArray()); // that fine SecretKeySpec secretKey = new SecretKeySpec(secret, "AES"); // SecureRandom should either be slow or be implemented in hardware SecureRandom random = new SecureRandom(); // first create the cipher Cipher eCipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); // filled with 00h characters first, use Cipher instance so you can switch algorithms byte[] realIV = new byte[eCipher.getBlockSize()]; // actually fill with random random.nextBytes(realIV); // MISSING: create IvParameterSpec IvParameterSpec ivSpec = new IvParameterSpec(realIV); // create the cipher using the IV eCipher.init(Cipher.ENCRYPT_MODE, secretKey, ivSpec); // NOTE: you should really not encrypt passwords for verification String stringToEncrypt = "mypassword"; // convert to bytes first, but don't use the platform encoding byte[] dataToEncrypt = stringToEncrypt.getBytes(Charset.forName("UTF-8")); // actually do the encryption using the data byte[] encryptedData = eCipher.doFinal(dataToEncrypt); 

Now it looks much better. I used the Apache commons codec to decode the hex string.

Please note that you need to save realIV with encryptedData and that you did not realIV integrity protection, for example. MAC (for passwords, you may not need this).

+4
source

I strongly suspect you want to make ecipher.doFinal(stringToEncrypt) , possibly after a series of doUpdate(...) if you have more lines.

.init() creates an encryption object, update() and doFinal() fills in the encrypted output and accepts plain text as input.

Of course, you will need to convert between String and an array of bytes .

+1
source

All Articles