I found this on the internet:
Basicly, what I want to do is instead of having the key set like
new byte[] { 'T', 'h', 'e', 'B', 'e', 's', 't',
'S', 'e', 'c', 'r','e', 't', 'K', 'e', 'y' };I want it to be random(but must be 16 bytes), and to have access to it(print it on the screen). Also, is there a way to set it as a string, instead of byte type?
32 Answers
A strong AES key will be 16, 24, or 32 bytes long. If you restrict the key to bytes that map to printable US-ASCII characters, the key will be weaker than expected, because its range is limited (to about 100 bits, rather than 128—many millions of times weaker). It would be better to use an encoding like hexadecimal, base-64 or base-85 to represent the key as text; of course, these representations will be longer.
To create a secure key, use a KeyGenerator that is based on a properly seeded cryptographic random number generator; providers will choose their own RNG if you don't specify one:
KeyGenerator gen = KeyGenerator.getInstance("AES");
gen.init(128); /* 128-bit AES */
SecretKey secret = gen.generateKey();
byte[] binary = secret.getEncoded();
String text = String.format("%032X", new BigInteger(+1, binary));
System.out.println(text);If you want, you can instantiate your own SecureRandom instance, using your preferred algorithm and provider, and pass it to the key generator via an overload of the init() method.
There are key derivation methods that attempt to mitigate the weaknesses of password-based keys, but a password-based key will always be more predictable.
2Basicly, what I want to do is instead of having the key set like
new byte[] { 'T', 'h', 'e', 'B', 'e', 's', 't', 'S', 'e', 'c', 'r','e', 't', 'K', 'e', 'y' };Good because that is terrible and unsafe. It's the worst secret key. Passwords are not keys and should not be used as such.
I want it to be random(but must be 16 bytes)
You want it to be secure random:
public static void main(final String ... args) throws Exception { final SecureRandom prng = new SecureRandom(); final byte[] aes128KeyData = new byte[128 / Byte.SIZE]; prng.nextBytes(aes128KeyData); final SecretKey aesKey = new SecretKeySpec(aes128KeyData, "AES"); System.out.println(toHex(aesKey.getEncoded()));
}
private static String toHex(final byte[] data) { final StringBuilder sb = new StringBuilder(data.length * 2); for (final byte b : data) { sb.append(String.format("%02X", b)); } return sb.toString();
}and to have access to it(print it on the screen).
See above.
Also, is there a way to set it as a string, instead of byte type?
Well, yes, you can decode the above hexadecimal string. But in the end the AES algorithm requires a binary key, binary plaintext and will generate binary output. The SecretKey class is little more than a wrapper around the byte array.
To do more conversions to and from strings, learn about character-encoding and encoding...