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 <[email protected]> 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.

Reply via email to