All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.bouncycastle.crypto.prng.SP800SecureRandomBuilder Maven / Gradle / Ivy

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.engines.DESedeEngine;
import org.bouncycastle.crypto.macs.HMac;
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).
 */
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. *

*/ 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. *

* @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. *

* @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 * @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. * * @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. * * @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. * * @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. * * @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. * * @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 String getAlgorithm() { return "HASH-DRBG-" + getSimplifiedName(digest); } 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 String getAlgorithm() { if (hMac instanceof HMac) { return "HMAC-DRBG-" + getSimplifiedName(((HMac)hMac).getUnderlyingDigest()); } return "HMAC-DRBG-" + hMac.getAlgorithmName(); } 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 String getAlgorithm() { if (blockCipher instanceof DESedeEngine) { return "CTR-DRBG-3KEY-TDES"; } return "CTR-DRBG-" + blockCipher.getAlgorithmName() + keySizeInBits; } public SP80090DRBG get(EntropySource entropySource) { return new CTRSP800DRBG(blockCipher, keySizeInBits, securityStrength, entropySource, personalizationString, nonce); } } private static String getSimplifiedName(Digest digest) { String name = digest.getAlgorithmName(); int dIndex = name.indexOf('-'); if (dIndex > 0 && !name.startsWith("SHA3")) { return name.substring(0, dIndex) + name.substring(dIndex + 1); } return name; } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy