If I could only type properly. It should read:
*It always only fails at the END OF input stream.*

On Thursday, June 12, 2014 10:32:45 AM UTC-7, gnugu wrote:
>
> NOTE2: When decrypting the file using
>
>     public void encryptDecrypt(InputStream input, OutputStream output) {
>         final int BUFFER_SIZE = 1024;
>
>         try {
>             CipherOutputStream cipherStream = new 
> CipherOutputStream(output,
>                     _cipher);
>
>             byte[] buffer = new byte[BUFFER_SIZE];
>             int count = -1;
>             while ((count = input.read(buffer)) != -1) {
>                 cipherStream.write(buffer, 0, count);
>             }
>             input.close();
>             cipherStream.close();
>         } catch (Exception e) {
>             Log.e(this.getClass().getName(), Log.getStackTraceString(e));
>             throw new RuntimeException(e);
>         }
>     }
>
> It always only fails at the and if input stream. The count is proper and 
> is passed properly to CipherOutputStream (see code above). Beats me.
>
>
> On Thursday, June 12, 2014 10:30:48 AM UTC-7, gnugu wrote:
>>
>> NOTE: By 'text' in the post above I mean a short data from sql db. In 
>> which case I use doFinal(data) and am not using cipher streams at all.
>>
>>
>> On Thursday, June 12, 2014 9:44:35 AM UTC-7, gnugu wrote:
>>>
>>> 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 <rho...@gmail.com> 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 android-developers@googlegroups.com
To unsubscribe from this group, send email to
android-developers+unsubscr...@googlegroups.com
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 android-developers+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to