<PackageReference Include="BouncyCastle.Cryptography" Version="2.5.0" />

SP800SecureRandomBuilder

using Org.BouncyCastle.Crypto.Prng.Drbg; using Org.BouncyCastle.Security; using System; namespace Org.BouncyCastle.Crypto.Prng { public class SP800SecureRandomBuilder { private class HashDrbgProvider : IDrbgProvider { private readonly IDigest mDigest; private readonly byte[] mNonce; private readonly byte[] mPersonalizationString; private readonly int mSecurityStrength; public HashDrbgProvider(IDigest digest, byte[] nonce, byte[] personalizationString, int securityStrength) { mDigest = digest; mNonce = nonce; mPersonalizationString = personalizationString; mSecurityStrength = securityStrength; } public ISP80090Drbg Get(IEntropySource entropySource) { return new HashSP800Drbg(mDigest, mSecurityStrength, entropySource, mPersonalizationString, mNonce); } } private class HMacDrbgProvider : IDrbgProvider { private readonly IMac mHMac; private readonly byte[] mNonce; private readonly byte[] mPersonalizationString; private readonly int mSecurityStrength; public HMacDrbgProvider(IMac hMac, byte[] nonce, byte[] personalizationString, int securityStrength) { mHMac = hMac; mNonce = nonce; mPersonalizationString = personalizationString; mSecurityStrength = securityStrength; } public ISP80090Drbg Get(IEntropySource entropySource) { return new HMacSP800Drbg(mHMac, mSecurityStrength, entropySource, mPersonalizationString, mNonce); } } private class CtrDrbgProvider : IDrbgProvider { private readonly IBlockCipher mBlockCipher; private readonly int mKeySizeInBits; private readonly byte[] mNonce; private readonly byte[] mPersonalizationString; private readonly int mSecurityStrength; public CtrDrbgProvider(IBlockCipher blockCipher, int keySizeInBits, byte[] nonce, byte[] personalizationString, int securityStrength) { mBlockCipher = blockCipher; mKeySizeInBits = keySizeInBits; mNonce = nonce; mPersonalizationString = personalizationString; mSecurityStrength = securityStrength; } public ISP80090Drbg Get(IEntropySource entropySource) { return new CtrSP800Drbg(mBlockCipher, mKeySizeInBits, mSecurityStrength, entropySource, mPersonalizationString, mNonce); } } private readonly SecureRandom mRandom; private readonly IEntropySourceProvider mEntropySourceProvider; private byte[] mPersonalizationString; private int mSecurityStrength = 256; private int mEntropyBitsRequired = 256; public SP800SecureRandomBuilder() : this(CryptoServicesRegistrar.GetSecureRandom(), false) { } public SP800SecureRandomBuilder(SecureRandom entropySource, bool predictionResistant) { if (entropySource == null) throw new ArgumentNullException("entropySource"); mRandom = entropySource; mEntropySourceProvider = new BasicEntropySourceProvider(entropySource, predictionResistant); } public SP800SecureRandomBuilder(IEntropySourceProvider entropySourceProvider) { mRandom = null; mEntropySourceProvider = entropySourceProvider; } public SP800SecureRandomBuilder SetPersonalizationString(byte[] personalizationString) { mPersonalizationString = personalizationString; return this; } public SP800SecureRandomBuilder SetSecurityStrength(int securityStrength) { mSecurityStrength = securityStrength; return this; } public SP800SecureRandomBuilder SetEntropyBitsRequired(int entropyBitsRequired) { mEntropyBitsRequired = entropyBitsRequired; return this; } public SP800SecureRandom BuildHash(IDigest digest, byte[] nonce, bool predictionResistant) { return new SP800SecureRandom(mRandom, mEntropySourceProvider.Get(mEntropyBitsRequired), new HashDrbgProvider(digest, nonce, mPersonalizationString, mSecurityStrength), predictionResistant); } public SP800SecureRandom BuildCtr(IBlockCipher cipher, int keySizeInBits, byte[] nonce, bool predictionResistant) { return new SP800SecureRandom(mRandom, mEntropySourceProvider.Get(mEntropyBitsRequired), new CtrDrbgProvider(cipher, keySizeInBits, nonce, mPersonalizationString, mSecurityStrength), predictionResistant); } public SP800SecureRandom BuildHMac(IMac hMac, byte[] nonce, bool predictionResistant) { return new SP800SecureRandom(mRandom, mEntropySourceProvider.Get(mEntropyBitsRequired), new HMacDrbgProvider(hMac, nonce, mPersonalizationString, mSecurityStrength), predictionResistant); } } }