3

I found this on the internet: http://www.code2learn.com/2011/06/encryption-and-decryption-of-data-using.html

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?

  • You can get a byte array from a String using: "TheBestSecretKey".getBytes("UTF-8");You can generate a random string sequence and get the bytes the same way. Check out the answer http://stackoverflow.com/questions/41107/how-to-generate-a-random-alpha-numeric-string – Cratylus Nov 25 '13 at 22:44
  • I want to get the string from the byte sequence, not byte from string. What I want is actually have the user input the key instead of it being an IV(initialisation vector). –  Nov 25 '13 at 22:58
  • 1
    That's a terrible example. It will use ECB, and it confuses passwords with keys. Cannot get much worse in so few lines. – Maarten Bodewes Nov 25 '13 at 23:48

2 Answers2

8

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.

erickson
  • 265,237
  • 58
  • 395
  • 493
  • It prints something like C78857B2C06293AABAA3332A1A80A684 which should have 16 characters length. Why does it have double? Also, what if I want to make a 192-bit key aka 24 characters long? Obviously I change gen.init(192), but it will have 48 characters length. –  Nov 26 '13 at 10:00
  • 1
    @user2995645 Because it's a hexadecimal encoding. It's 16 bytes. Did you read my answer? Not to put too fine a point on it, but keys are *binary,* a string of bits, *not text,* a string of characters. A 192-bit key would be 48 hexadecimal characters, 32 characters in base-64, or 30 characters in base-85. If you only use printable characters, a 16-character key is only 105 bits, a 24-character key is only 158 bits. – erickson Nov 26 '13 at 17:16
1

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' };

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 and ...

Maarten Bodewes
  • 90,524
  • 13
  • 150
  • 263