C. Anon
C. Anon

Reputation: 23

How to generate secret key using SecureRandom.getInstanceStrong()?

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

Answers (1)

Maarten Bodewes
Maarten Bodewes

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

Related Questions