7

AES key may be generate by this code

KeyGenerator kgen = KeyGenerator.getInstance("AES");
kgen.init(128); 

but

If I have a "very reliable" method of generating random numbers can I use it in such a way

SecureRandom rnd = new SecureRandom();
byte[] key = new byte[16];
rnd.nextBytes(key);

is key obtained by this method reliable ?

or it ONLY must generated by some SPECIAL algorithm

terentev
  • 654
  • 1
  • 8
  • 10

4 Answers4

14

The AES key can be any 128 bits. It should be be practically unguessable, whatever the method of creating it.

For Example:

SecureRandom sr = new SecureRandom()

key = new byte[16];
iv = new byte[16];

sr.nextBytes(key);
sr.nextBytes(iv);

Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(key,"AES"), new IvParameterSpec(IV));

SecretKeySpec, by the way, is just a thin wrapper around a byte[] --- it does not transform the key in any way. No "special algorithm".

maybeWeCouldStealAVan
  • 15,492
  • 2
  • 23
  • 32
  • this is I wanted to hear, I hope this is true :) – terentev Apr 20 '12 at 20:16
  • 1
    @user249654 Yes, it is. And don't use plain `java.util.Random` like in the question, use at least something like SecureRandom to avoid a fast brute-forcing of your key. – Paŭlo Ebermann Apr 21 '12 at 14:00
  • @PaŭloEbermann Please also see [this excellent question](http://stackoverflow.com/q/18228579/589259) by Thomas. That it is secure does not necessarily mean that it is the best method of generating the secret key. – Maarten Bodewes Aug 14 '13 at 12:32
3

To add to the other answers ... I believe that the reason that the basic Random functions aren't secure are two reasons:

  1. Slight statistical biases that are acceptable for non-security related situations, but narrow the distributions unacceptably for security applications.
  2. They are seeded by the system DATETIME. Even knowing WHEN you generated your key - to a poor accuracy of +/- 6 months - would significantly reduce the brute force search space.
Jason Kleban
  • 20,024
  • 18
  • 75
  • 125
  • 1
    Note that this answer was provided *before* the question was changed from `Random` to `SecureRandom` - which is cheating in my opinion. – Maarten Bodewes Aug 14 '13 at 12:30
1

You can add a random algorithm using SecureRandom :

    KeyGenerator keyGen = KeyGenerator.getInstance("AES");
    SecureRandom random = new SecureRandom(); // cryptograph. secure random 
    keyGen.init(random); 
    SecretKey secretKey = keyGen.generateKey();
alain.janinm
  • 19,951
  • 10
  • 65
  • 112
1

It sounds like you're trying to generate an AES key based on a password.

If this is the case, you can use javax.crypto.SecretKeyFactory's generateSecret method, passing in a javax.crypto.spec.PBEKeySpec as the parameter. The PBEKeySpec allows to to specify the password as an argument to its constructor.

Tom
  • 18,685
  • 15
  • 71
  • 81
  • Yes but i unlike PBEKeySpec :) – terentev Apr 20 '12 at 20:05
  • i dont know what PBEKeySpec do (in it) ? :) – terentev Apr 20 '12 at 20:14
  • 3
    PBEKeySpecis an implementation of *[PBKDF2](http://en.wikipedia.org/wiki/PBKDF2)*, a standard algorithm which uses many rounds of a *[hash algorithm](http://en.wikipedia.org/wiki/HMAC)* and a salt to produce a binary key of a given length based on a passphrase. Essentially, it's a specialized secure pseudorandom generator using the passphrase and salt as a seed. If you're generating secure random numbers as your keys, then you don't need it. If you're using a human-memorizable passphrase to generate your key, PBKDF2 is a good choice to protect against dictionary attacks. – maybeWeCouldStealAVan Apr 20 '12 at 22:14
  • Oops, sloppy editing on my part. `SecretKeyFactory` can generate a secret key given the pashphrase, salt, number of rounds, and desired key size specified in a `PBEKeySpec` object. It does so using any of several standard algorithms. One, for example, is "PBKDF2WITHHMACSHA1", a specific form of the PBKDF2 algorithm. – maybeWeCouldStealAVan Apr 21 '12 at 17:32