package org.bouncycastle.crypto.prng;

import java.security.SecureRandom;

import org.bouncycastle.crypto.BlockCipher;
import org.bouncycastle.crypto.CryptoServicesRegistrar;
import org.bouncycastle.crypto.Digest;
import org.bouncycastle.crypto.Mac;
import org.bouncycastle.crypto.prng.drbg.CTRSP800DRBG;
import org.bouncycastle.crypto.prng.drbg.HMacSP800DRBG;
import org.bouncycastle.crypto.prng.drbg.HashSP800DRBG;
import org.bouncycastle.crypto.prng.drbg.SP80090DRBG;
import org.bouncycastle.util.Arrays;

Builder class for making SecureRandom objects based on SP 800-90A Deterministic Random Bit Generators (DRBG).
/** * Builder class for making SecureRandom objects based on SP 800-90A Deterministic Random Bit Generators (DRBG). */
public class SP800SecureRandomBuilder { private final SecureRandom random; private final EntropySourceProvider entropySourceProvider; private byte[] personalizationString; private int securityStrength = 256; private int entropyBitsRequired = 256;
Basic constructor, creates a builder using an EntropySourceProvider based on the default SecureRandom with predictionResistant set to false.

Any SecureRandom created from a builder constructed like this will make use of input passed to SecureRandom.setSeed() if the default SecureRandom does for its generateSeed() call.

/** * Basic constructor, creates a builder using an EntropySourceProvider based on the default SecureRandom with * predictionResistant set to false. * <p> * Any SecureRandom created from a builder constructed like this will make use of input passed to SecureRandom.setSeed() if * the default SecureRandom does for its generateSeed() call. * </p> */
public SP800SecureRandomBuilder() { this(CryptoServicesRegistrar.getSecureRandom(), false); }
Construct a builder with an EntropySourceProvider based on the passed in SecureRandom and the passed in value for prediction resistance.

Any SecureRandom created from a builder constructed like this will make use of input passed to SecureRandom.setSeed() if the passed in SecureRandom does for its generateSeed() call.

Params:
  • entropySource – the SecureRandom acting as a source of entropy for DRBGs made by this builder.
  • predictionResistant – true if the SecureRandom seeder can be regarded as predictionResistant.
/** * Construct a builder with an EntropySourceProvider based on the passed in SecureRandom and the passed in value * for prediction resistance. * <p> * Any SecureRandom created from a builder constructed like this will make use of input passed to SecureRandom.setSeed() if * the passed in SecureRandom does for its generateSeed() call. * </p> * @param entropySource the SecureRandom acting as a source of entropy for DRBGs made by this builder. * @param predictionResistant true if the SecureRandom seeder can be regarded as predictionResistant. */
public SP800SecureRandomBuilder(SecureRandom entropySource, boolean predictionResistant) { this.random = entropySource; this.entropySourceProvider = new BasicEntropySourceProvider(random, predictionResistant); }
Create a builder which makes creates the SecureRandom objects from a specified entropy source provider.

Note: If this constructor is used any calls to setSeed() in the resulting SecureRandom will be ignored.

Params:
  • entropySourceProvider – a provider of EntropySource objects.
/** * Create a builder which makes creates the SecureRandom objects from a specified entropy source provider. * <p> * <b>Note:</b> If this constructor is used any calls to setSeed() in the resulting SecureRandom will be ignored. * </p> * @param entropySourceProvider a provider of EntropySource objects. */
public SP800SecureRandomBuilder(EntropySourceProvider entropySourceProvider) { this.random = null; this.entropySourceProvider = entropySourceProvider; }
Set the personalization string for DRBG SecureRandoms created by this builder
Params:
  • personalizationString – the personalisation string for the underlying DRBG.
Returns:the current builder.
/** * Set the personalization string for DRBG SecureRandoms created by this builder * @param personalizationString the personalisation string for the underlying DRBG. * @return the current builder. */
public SP800SecureRandomBuilder setPersonalizationString(byte[] personalizationString) { this.personalizationString = Arrays.clone(personalizationString); return this; }
Set the security strength required for DRBGs used in building SecureRandom objects.
Params:
  • securityStrength – the security strength (in bits)
Returns:the current builder.
/** * Set the security strength required for DRBGs used in building SecureRandom objects. * * @param securityStrength the security strength (in bits) * @return the current builder. */
public SP800SecureRandomBuilder setSecurityStrength(int securityStrength) { this.securityStrength = securityStrength; return this; }
Set the amount of entropy bits required for seeding and reseeding DRBGs used in building SecureRandom objects.
Params:
  • entropyBitsRequired – the number of bits of entropy to be requested from the entropy source on each seed/reseed.
Returns:the current builder.
/** * Set the amount of entropy bits required for seeding and reseeding DRBGs used in building SecureRandom objects. * * @param entropyBitsRequired the number of bits of entropy to be requested from the entropy source on each seed/reseed. * @return the current builder. */
public SP800SecureRandomBuilder setEntropyBitsRequired(int entropyBitsRequired) { this.entropyBitsRequired = entropyBitsRequired; return this; }
Build a SecureRandom based on a SP 800-90A Hash DRBG.
Params:
  • digest – digest algorithm to use in the DRBG underneath the SecureRandom.
  • nonce – nonce value to use in DRBG construction.
  • predictionResistant – specify whether the underlying DRBG in the resulting SecureRandom should reseed on each request for bytes.
Returns:a SecureRandom supported by a Hash DRBG.
/** * Build a SecureRandom based on a SP 800-90A Hash DRBG. * * @param digest digest algorithm to use in the DRBG underneath the SecureRandom. * @param nonce nonce value to use in DRBG construction. * @param predictionResistant specify whether the underlying DRBG in the resulting SecureRandom should reseed on each request for bytes. * @return a SecureRandom supported by a Hash DRBG. */
public SP800SecureRandom buildHash(Digest digest, byte[] nonce, boolean predictionResistant) { return new SP800SecureRandom(random, entropySourceProvider.get(entropyBitsRequired), new HashDRBGProvider(digest, nonce, personalizationString, securityStrength), predictionResistant); }
Build a SecureRandom based on a SP 800-90A CTR DRBG.
Params:
  • cipher – the block cipher to base the DRBG on.
  • keySizeInBits – key size in bits to be used with the block cipher.
  • nonce – nonce value to use in DRBG construction.
  • predictionResistant – specify whether the underlying DRBG in the resulting SecureRandom should reseed on each request for bytes.
Returns: a SecureRandom supported by a CTR DRBG.
/** * Build a SecureRandom based on a SP 800-90A CTR DRBG. * * @param cipher the block cipher to base the DRBG on. * @param keySizeInBits key size in bits to be used with the block cipher. * @param nonce nonce value to use in DRBG construction. * @param predictionResistant specify whether the underlying DRBG in the resulting SecureRandom should reseed on each request for bytes. * @return a SecureRandom supported by a CTR DRBG. */
public SP800SecureRandom buildCTR(BlockCipher cipher, int keySizeInBits, byte[] nonce, boolean predictionResistant) { return new SP800SecureRandom(random, entropySourceProvider.get(entropyBitsRequired), new CTRDRBGProvider(cipher, keySizeInBits, nonce, personalizationString, securityStrength), predictionResistant); }
Build a SecureRandom based on a SP 800-90A HMAC DRBG.
Params:
  • hMac – HMAC algorithm to use in the DRBG underneath the SecureRandom.
  • nonce – nonce value to use in DRBG construction.
  • predictionResistant – specify whether the underlying DRBG in the resulting SecureRandom should reseed on each request for bytes.
Returns:a SecureRandom supported by a HMAC DRBG.
/** * Build a SecureRandom based on a SP 800-90A HMAC DRBG. * * @param hMac HMAC algorithm to use in the DRBG underneath the SecureRandom. * @param nonce nonce value to use in DRBG construction. * @param predictionResistant specify whether the underlying DRBG in the resulting SecureRandom should reseed on each request for bytes. * @return a SecureRandom supported by a HMAC DRBG. */
public SP800SecureRandom buildHMAC(Mac hMac, byte[] nonce, boolean predictionResistant) { return new SP800SecureRandom(random, entropySourceProvider.get(entropyBitsRequired), new HMacDRBGProvider(hMac, nonce, personalizationString, securityStrength), predictionResistant); } private static class HashDRBGProvider implements DRBGProvider { private final Digest digest; private final byte[] nonce; private final byte[] personalizationString; private final int securityStrength; public HashDRBGProvider(Digest digest, byte[] nonce, byte[] personalizationString, int securityStrength) { this.digest = digest; this.nonce = nonce; this.personalizationString = personalizationString; this.securityStrength = securityStrength; } public SP80090DRBG get(EntropySource entropySource) { return new HashSP800DRBG(digest, securityStrength, entropySource, personalizationString, nonce); } } private static class HMacDRBGProvider implements DRBGProvider { private final Mac hMac; private final byte[] nonce; private final byte[] personalizationString; private final int securityStrength; public HMacDRBGProvider(Mac hMac, byte[] nonce, byte[] personalizationString, int securityStrength) { this.hMac = hMac; this.nonce = nonce; this.personalizationString = personalizationString; this.securityStrength = securityStrength; } public SP80090DRBG get(EntropySource entropySource) { return new HMacSP800DRBG(hMac, securityStrength, entropySource, personalizationString, nonce); } } private static class CTRDRBGProvider implements DRBGProvider { private final BlockCipher blockCipher; private final int keySizeInBits; private final byte[] nonce; private final byte[] personalizationString; private final int securityStrength; public CTRDRBGProvider(BlockCipher blockCipher, int keySizeInBits, byte[] nonce, byte[] personalizationString, int securityStrength) { this.blockCipher = blockCipher; this.keySizeInBits = keySizeInBits; this.nonce = nonce; this.personalizationString = personalizationString; this.securityStrength = securityStrength; } public SP80090DRBG get(EntropySource entropySource) { return new CTRSP800DRBG(blockCipher, keySizeInBits, securityStrength, entropySource, personalizationString, nonce); } } }