Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java AES decryption detect incorrect key

I am writing android app that makes AES encryption/decryption of files. I want to be able to detect if incorrect password is specified and thus not matching key is derived for decryption. I am using AES/CBC/PKCS7Padding with 256 bit key. If I do cipher.doFinal() I can try/catch the BadPaddingException and it tells me that something is wrong and probably key was incorrect. But if I use CipherInputStream to read encrypted file, I get no feedback on correctness of padding. So if I deliberately specify incorrect password it decrypts file, then reports that everything is ok, however decrypted file is a total junk. So my question is how to detect bad padding when using CipherInputStream?

like image 248
Alex Amiryan Avatar asked Nov 01 '25 05:11

Alex Amiryan


2 Answers

Prepend some known header to your data. Decrypt it first and if it doesn't match what you expected, stop and return error.

like image 56
Nikolay Elenkov Avatar answered Nov 02 '25 18:11

Nikolay Elenkov


Try and use GCM mode instead (Java 7 or Bouncy Castle provider). The trick with padding is that sometimes it is correct after the message has been altered (once in 256 times, approximately). GCM mode will add intergrity protection, so any alteration will result in an exception derived from BadPaddingException.

One thing though: you should prepend a (random) nonce when encrypting with GCM (actually a rule for CBC mode too, but the implications of using a non-random IV in CBC are less severe).

Note that you need to perform the final calculation to get a badpaddingexception, so don't forget to close or end the underlying stream. This is probably your current issue.

[EDIT]: this is not the answer, but the input could be used to generate a better CipherInputStream, see my other answer on this question.

like image 23
Maarten Bodewes Avatar answered Nov 02 '25 19:11

Maarten Bodewes