I read some examples about using Java Cipher to encrypt and decrypt data. For example:
KeyGenerator keyGenerator = KeyGenerator.getInstance("AES");
SecureRandom secureRandom = new SecureRandom();
keyGenerator.init(256, secureRandom);
SecretKey secretKey = keyGenerator.generateKey();
Cipher c = Cipher.getInstance("AES/CBC/PKCS5Padding");
c.init(Cipher.ENCRYPT_MODE, secretKey);
I have 2 questions about the decryption process.
- Although an IV is required, we can leave it implicit by using
Cipher.init(Cipher.ENCRYPT_MODE, Key). A random IV will be automatically applied to it. However, in decryption mode, the same IV must be used. Does it mean only theCipher.init(int opmode, Key key, AlgorithmParameters params)should be used and the IV should be get from the encryption, stored and passed here?
Beside the '''KeyGenerator''', I also saw the example to generate key with '''SecretKeyFactory''':
String key = ...
SecretKeyFactory factory = SecretKeyFactory.getInstance("DES");
SecretKeySpec keySpec = factory.generateSecret(new DESKeySpec(key));
I suppose I can use it for AES if I change last line to
SecretKeySpec keySpec = factory.generateSecret(new SecretKeySpec(key,"AES"));
- I am confused about when to use
SecretKeyFactoryto generate a key and when to useKeyGenerator. It seems the latter is generate a random key, the former is generated from a given key material. So does it mean in decryption mode, only SecretKeyFactory can be used?
Yes, exactly that, unless you are able to communicate it in other ways. Generally though the IV is randomized during encryption, then prefixed to the ciphertext. For AES-CBC it is always the same size as the block size: 16 bytes.
Yes, although for AES there is a neat little shortcut; you can simply do:
and be done with it. This is because
SecretKeySpecimplementsSecretKey. For 3DES keys that's not a good idea because it would mean that the parity bits of DES are not set correctly. However, modern keys such as AES keys and HMAC keys solely consist of random data, so for those it is fine. There is one caveat: it will be a problem if you try and generate a key in a hardware device that way: it must be kept in software.Note that I won't delve too much in key management and how keys need to be created. I've answered that question here, although that answer is certainly far from complete. Heck you could use dice and share the numbers over the phone for all I care :)