/* See LICENSE for licensing and NOTICE for copyright. */
package org.cryptacular.generator;
import java.security.SecureRandom;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import org.bouncycastle.crypto.BlockCipher;
import org.bouncycastle.crypto.digests.SHA256Digest;
import org.bouncycastle.crypto.prng.SP800SecureRandomBuilder;
import org.cryptacular.util.NonceUtil;
/**
* Factory class with static methods for generating {@link SecretKey}s.
*
* @author Middleware Services
*/
public final class SecretKeyGenerator
{
/** Private constructor of static class. */
private SecretKeyGenerator() {}
/**
* Generates a symmetric encryption key whose size is equal to the cipher block size.
*
* @param cipher Cipher with with key will be used.
*
* @return Symmetric encryption key.
*/
public static SecretKey generate(final BlockCipher cipher)
{
return generate(cipher.getBlockSize() * 8, cipher);
}
/**
* Generates a symmetric encryption key of the given length.
*
* @param bitLength Desired key length in bits.
* @param cipher Cipher with with key will be used.
*
* @return Symmetric encryption key.
*/
public static SecretKey generate(final int bitLength, final BlockCipher cipher)
{
// Want as much nonce data as key bits
final byte[] nonce = NonceUtil.timestampNonce((bitLength + 7) / 8);
return generate(bitLength, cipher, new SP800SecureRandomBuilder().buildHash(new SHA256Digest(), nonce, false));
}
/**
* Generates a symmetric encryption key of the given length.
*
* @param bitLength Desired key length in bits.
* @param cipher Cipher with with key will be used.
* @param random Randomness provider for key generation.
*
* @return Symmetric encryption key.
*/
public static SecretKey generate(final int bitLength, final BlockCipher cipher, final SecureRandom random)
{
// Round up for bit lengths that are not a multiple of 8
final byte[] key = new byte[(bitLength + 7) / 8];
random.nextBytes(key);
return new SecretKeySpec(key, cipher.getAlgorithmName());
}
}