On DES and AES: use AES.
DES and AES are block ciphers: they encrypt data by "blocks", where a block is a 64-bit (for DES) or 128-bit (for AES) quantity. To encrypt a "message" which is not a single block, you need to use a "chaining mode" and possibly a "padding": the chaining mode defines how data is split into blocks and assembled again, and the padding consists in extra bytes added at the end of the message so that the total length is appropriate for whatever splitting the chaining mode uses. The padding must be such that, upon decryption, it can unambiguously removed.
The "standard" chaining mode and padding are called, respectively, CBC and PKCS#5. The PKCS#5 padding adds between 1 and n bytes, where n is the block length (hence 8 for DES, 16 for AES), so that the total padded length is a multiple of n. CBC links blocks together and requires an Initialization Vector (IV) which should be a sequence of n random bytes; it is very important that the IV bytes are generated with a cryptographically strong random number generator (i.e. java.security.SecureRandom
) and that you generate a new IV for each message. The IV must also be sent along (unencrypted) with the encrypted message, because the receiver will need it to decrypt the data.
For the block cipher itself: DES comes in two flavors, the "original" DES, and "Triple-DES", also called "3DES" or sometimes simply "DES". The original DES uses a 64-bit key, out of which 8 bits are ignored, so the effective key length is 56 bits, and that's too short for security. 3DES uses a 192-bit key (24 bits are ignored, so 168-bit effective key length) and is believed to be robust; it is also three times slower than DES, which is already not that fast.
AES was designed to replace DES, and is generally thought to be better in all respects. AES has three flavors, dubbed AES-128, AES-192 and AES-256, which differ by the key length (of 128, 192 and 256 bits, respectively). 128 bits are more than enough for security, and longer keys imply a slight computational overhead, so a 128-bit key is preferred.
To get a list of algorithms supported by a Java virtual machine, try this:
import java.security.Provider;
import java.security.Security;
import java.util.Map;
import java.util.TreeSet;
public class ListAlgo {
public static void main(String[] args)
{
TreeSet<String> algos = new TreeSet<String>();
for (Provider p : Security.getProviders()) {
for (Map.Entry<Object, Object> e : p.entrySet()) {
String s = e.getKey().toString()
+ " -> " + e.getValue().toString();
if (s.startsWith("Alg.Alias.")) {
s = s.substring(10);
}
algos.add(s);
}
}
for (String a : algos) {
System.out.println(a);
}
}
}
(This is for "normal" Java; for Android you will probably need to change things a bit with regards to the final output.)
The encryption algorithms will be those where the string begins by "Cipher.
". Anyway, if you want the most widely supported algorithm combination, it will be "AES/CBC/PKCS5Padding
" with a 128-bit key: if a given Android-based supports a single cipher, it will support that one.
If you are in a situation where encryption is warranted, then chances are that you will also need an integrity check; see javax.crypto.Mac
. For a MAC, when in doubt, use HMAC with SHA-256 (if SHA-256 is not supported, fallback to HMAC with SHA-1).