Hi Nikolay, Thanks for your response. I have tried _cipher = Cipher.getInstance(CIPHER_PROVIDER, "BC"); before. Makes no difference. I fact on my Android 4.4.3 when I do not specify "BC" it still instantiates BouncyCastle.
What bothers me is that when I'm decrypting texts it works fine. Fails only when I decrypt binary file AND that only happens random. Same file can be decrypted and on the second/third/random attempt it throws an error. Any ideas what that might be? Thanks. On Tuesday, June 10, 2014 1:59:16 AM UTC-7, Nikolay Elenkov wrote: > > On Sat, Jun 7, 2014 at 6:52 AM, gnugu <[email protected] <javascript:>> > wrote: > > Hi I am getting the following exception, when decrypting a file on > Android > > based on user supplied password: > > > > Caused by: java.lang.ArrayIndexOutOfBoundsException: src.length=1024 > > srcPos=1008 dst.length=16 dstPos=16 length=16 > > at java.lang.System.arraycopy(Native Method) > > at > > > com.android.org.bouncycastle.crypto.paddings.PaddedBufferedBlockCipher.processBytes(PaddedBufferedBlockCipher.java:221) > > > > at > > > com.android.org.bouncycastle.jcajce.provider.symmetric.util.BaseBlockCipher$BufferedGenericBlockCipher.processBytes(BaseBlockCipher.java:882) > > > > at > > > com.android.org.bouncycastle.jcajce.provider.symmetric.util.BaseBlockCipher.engineUpdate(BaseBlockCipher.java:674) > > > > at javax.crypto.Cipher.update(Cipher.java:893) > > at > javax.crypto.CipherOutputStream.write(CipherOutputStream.java:95) > > > > It happens randomly and from the crash reports on Google Play Store only > on > > Android 4+. It used to work on older versions. > > > > My Crypto wrapper: > > > > > private static final String CIPHER_PROVIDER = "AES"; > > _cipher = Cipher.getInstance(CIPHER_PROVIDER); > > > This may have different results on different providers/versions. The > default cypto > provider in newer version of Android is based AndroidOpenSSL, but previous > versions used BouncyCastle. The proper way to fix this is to specify the > full Cipher transformation instead of just "AES" ("AES/CBC/PKCS5", etc.). > Then you'll need to deal with IVs properly, of course. > > You could probably get away for now with explicitly specifying the > BouncyCastle > provider with something like this to get the same behaviour as before: > > _cipher = Cipher.getInstance(CIPHER_PROVIDER, "BC"); > > > > > > When I changed the code to this: > > > ... > > byte[] buffer = new byte[BUFFER_SIZE]; > > int count = -1; > > while ((count = input.read(buffer)) != -1) { > > > > byte[] result = null; > > if (count == BUFFER_SIZE) { > > result = _cipher.update(buffer, 0, count); > > } else { > > result = _cipher.doFinal(buffer, 0, count); > > } > > > > if (result != null) { > > output.write(result); > > } > ... > > > > I'm getting > > > > javax.crypto.BadPaddingException: pad block corrupted > > > > You should only write as many bytes as you read, otherwise > you get garbage. In any case, using raw buffers doesn't fix > your main problem, so see above. > -- You received this message because you are subscribed to the Google Groups "Android Developers" group. To post to this group, send email to [email protected] To unsubscribe from this group, send email to [email protected] For more options, visit this group at http://groups.google.com/group/android-developers?hl=en --- You received this message because you are subscribed to the Google Groups "Android Developers" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. For more options, visit https://groups.google.com/d/optout.

