Reputation: 23
How to generate secret key using SecureRandom.getInstanceStrong()?
With this code I can receive byte array with random values. Is there any easy way to generate key of a given length (256 bits, for example), type (int, String) and format (hex, bin, dec)?
package com.company;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
public class KeyGen {
public void generate() throws NoSuchAlgorithmException {
SecureRandom random = SecureRandom.getInstanceStrong();
byte[] values = new byte[32]; // 256 bit
random.nextBytes(values);
StringBuilder sb = new StringBuilder();
for (byte b : values) {
sb.append(String.format("%02x", b));
}
System.out.print("Key: ");
System.out.println(sb.toString());
}
}
Output:
Key: 8fcea84897f48f575c22441ece4e7ddb43ac08cd2c1a83fca46c080768468059
Upvotes: 2
Views: 8199
Reputation: 94038
Keys should be of a specific type, e.g. AES. They should preferably be kept inside a SecretKey
instance or a similar Key
derived class.
Keys for modern symmetric ciphers consist of bits. Usually you would not need a human/String representation of them (and this could actually harm security). Store them in a KeyStore
or derive them from a password instead. If you do encode them then the representation format is inconsequential, as long as you don't loose your data during the conversions.
This is probably the best way to generate a strong AES key:
public class GenerateStrongAESKey {
public static SecretKey generateStrongAESKey(final int keysize) {
final KeyGenerator kgen;
try {
kgen = KeyGenerator.getInstance("AES");
} catch (final NoSuchAlgorithmException e) {
throw new RuntimeException("AES key generator should always be available in a Java runtime", e);
}
final SecureRandom rng;
try {
rng = SecureRandom.getInstanceStrong();
} catch (final NoSuchAlgorithmException e) {
throw new RuntimeException("No strong secure random available to generate strong AES key", e);
}
// already throws IllegalParameterException for wrong key sizes
kgen.init(keysize, rng);
return kgen.generateKey();
}
public static void main(String[] args) {
SecretKey strongAESKey = generateStrongAESKey(256);
// well, if you must have a human readable string, here it is
// but you've been warned
System.out.println(toHex(strongAESKey.getEncoded()));
}
private static String toHex(final byte[] data) {
final StringBuilder sb = new StringBuilder(data.length * 2);
for (byte b : data) {
sb.append(String.format("%02X", b));
}
return sb.toString();
}
}
Note: this requires the unlimited strength jurisdictional files for the Oracle runtime environment for keys > 128 bits.
Upvotes: 4