Data encryption on Android, AES-GCM or simple AES?

My team should develop a solution for encrypting binary data (stored as byte[] ) in the context of an Android application written in Java. The encrypted data will be transmitted and stored in various ways, during which it is impossible to exclude data corruption. In the end, another Android application (again written in Java) will have to decrypt the data.

It has already been decided that the encryption algorithm should be AES with a 256-bit key. However, I would like to make an informed decision about which AES implementation and / or “mode” we should use. I read about what is called GCM mode, and we did some tests with it (using BouncyCastle / SpongyCastle), but it’s not entirely clear to me what AES-GCM is for and what it “buys” us compared to regular AES - and is there any compromise that needs to be taken into account.

Here is the list of problems / requirements / questions that we have:

  • Filling: the data we need to encrypt will not always be 128-bit short, so add-on should be added for AES implementation / mode, but only if necessary. I had the impression that a simple AES implementation, such as provided by javax.crypto.Cipher , would not do this, but initial tests showed that it was. Therefore, I assume that the requirement of filling in itself is not a reason to resort to something like GCM instead of "simple" AES. It is right?

  • Authentication: We need a reliable way to detect data corruption. However, ideally, we also want to determine when decryption is performed using the wrong key. Therefore, we want to be able to distinguish between these two cases. The reason I ended up looking at GCM was primarily related to this Stackoverflow question, where one of the respondents seems to imply that such a difference is possible using AES-GCM, although it does not provide a detailed explanation (not to mention about the code).

  • Minimize overhead . We need to limit the overhead of storing and transmitting encrypted data. Therefore, we want to find out if the choice for a specific implementation / AES mode affects the amount of overhead.

  • Encryption / Decryption Performance:. Although this is not the main problem, we are interested in how much the choice of a specific implementation / AES mode affects the encryption and decryption performance, both in terms of CPU time and memory size.

Thanks in advance for any tips, clarifications, and / or code examples.

EDIT: delnan gratefully pointed out that there is no such thing as "plain AES." Therefore, to clarify what I had in mind, this is using the native AES support in Java.
For example: Cipher localCipher = Cipher.getInstance("AES");

+8
android encryption aes bouncycastle aes-gcm
source share
1 answer

In 2012, the answer should go to GCM, if you do not have serious compatibility issues.

GCM is an authenticated encryption mode. It provides privacy (encryption), integrity and authentication (MAC) at a time.

So far, the normal modes of operation have been ECB (default is Java ), CBC, CTR, OFB, and some others. All of them provided only encryption. Confidentiality in itself is rarely used without integrity; it was necessary to combine such classic modes with integrity checks in a special way. Because cryptography is difficult to understand, often such combinations were unsafe, slower than necessary, or even both.

Authenticated encryption modes were (quite recently) created by cryptographers to solve this problem. GCM is one of the most successful: it was chosen by NIST , it is efficient, it does not have a patent, and it can carry Additional authenticated data (that is, data that remains clear, but for which you can authenticate). For other modes, see this excellent article by Matthew Green .

Getting started with your problems:

  • Padding: By default, Java uses the PKCS # 7 add-on. It works, but is often vulnerable to oracle indents that are best defeated by the MAC . GCM already implements MAC (called GMAC).

  • Authentication: AES-GCM uses only one AES key, not passwords. It will tell you if the AES key is incorrect or the payload has been tampered with, but such conditions are treated as one. Instead, you should use a suitable key derivation algorithm such as PBKDF2 or bcrypt to extract the AES key from the password. I don’t think it can always be determined whether the password was incorrect or the payload was changed, because the data necessary to verify the first one can always be corrupted. You can encrypt a small known string (with ECB AES), send it and use it to verify the password is correct.

  • Minimize overhead:. At the end of the day, all modes lead to the same overhead (about 10-20 bytes) if you want authentication. If you are not working with very small payloads, this point can be ignored.

  • Performance: GCM is pretty good in that it is an online mode (there is no need to buffer the entire payload, which means less memory), it is parallelized and requires one AES operation and one Galois multiplication by a plaintext block. Classic modes such as ECBs are faster (one AES operation for each block only), but - again - you must also consider integrity logic, which can be slower than GMAC.

Having said that, you need to know that GCM security is based on generating a good random number to create an IV.

+10
source share

All Articles