@Test public void createsSecureRandomInitialisedToUsePRNG() { final QuickEntropy quickEntropy = mock(QuickEntropy.class); final SP800SecureRandomBuilder sp800Builder = mock(SP800SecureRandomBuilder.class); when(sp800Builder.setSecurityStrength(anyInt())).thenReturn(sp800Builder); when(sp800Builder.setPersonalizationString(any())).thenReturn(sp800Builder); new PRNGSecureRandom(quickEntropy, sp800Builder); verify(sp800Builder).buildHash(any(SHA256Digest.class), eq(null), eq(false)); verify(sp800Builder).setSecurityStrength(256); verify(sp800Builder).setPersonalizationString(any()); }
/** * 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.randomNonce((bitLength + 7) / 8); return generate(bitLength, cipher, new SP800SecureRandomBuilder().buildHash(new SHA256Digest(), nonce, false)); }
HybridSecureRandom() { super(null, new HybridRandomProvider()); drbg = new SP800SecureRandomBuilder(new EntropySourceProvider() { public EntropySource get(final int bitsRequired) { return new SignallingEntropySource(bitsRequired); } }) .setPersonalizationString(Strings.toByteArray("Bouncy Castle Hybrid Entropy Source")) .buildHMAC(new HMac(new SHA512Digest()), baseRandom.generateSeed(32), false); // 32 byte nonce }
private static SecureRandom createBaseRandom(boolean isPredictionResistant) { if (System.getProperty("org.bouncycastle.drbg.entropysource") != null) { EntropySourceProvider entropyProvider = createEntropySource(); EntropySource initSource = entropyProvider.get(16 * 8); byte[] personalisationString = isPredictionResistant ? generateDefaultPersonalizationString(initSource.getEntropy()) : generateNonceIVPersonalizationString(initSource.getEntropy()); return new SP800SecureRandomBuilder(entropyProvider) .setPersonalizationString(personalisationString) .buildHash(new SHA512Digest(), Arrays.concatenate(initSource.getEntropy(), initSource.getEntropy()), isPredictionResistant); } else { SecureRandom randomSource = new HybridSecureRandom(); // needs to be done late, can't use static byte[] personalisationString = isPredictionResistant ? generateDefaultPersonalizationString(randomSource.generateSeed(16)) : generateNonceIVPersonalizationString(randomSource.generateSeed(16)); return new SP800SecureRandomBuilder(randomSource, true) .setPersonalizationString(personalisationString) .buildHash(new SHA512Digest(), randomSource.generateSeed(32), isPredictionResistant); } }
@Test public void reseedsUsingQuickEntropyOnEachNextByteCall() { final QuickEntropy quickEntropy = mock(QuickEntropy.class); final SP800SecureRandomBuilder sp800Builder = mock(SP800SecureRandomBuilder.class); final SP800SecureRandom sp800SecureRandom = mock(SP800SecureRandom.class); final byte[] entropy = {1, 2, 3, 4}; when(quickEntropy.getQuickEntropy()).thenReturn(entropy); when(sp800Builder.setSecurityStrength(anyInt())).thenReturn(sp800Builder); when(sp800Builder.setPersonalizationString(any())).thenReturn(sp800Builder); when(sp800Builder.buildHash(any(), any(), anyBoolean())).thenReturn(sp800SecureRandom); final PRNGSecureRandom prngSecureRandom = new PRNGSecureRandom(quickEntropy, sp800Builder); final byte[] bytes = new byte[] {}; prngSecureRandom.nextBytes(bytes); verify(quickEntropy, times(1)).getQuickEntropy(); verify(sp800SecureRandom).setSeed(entropy); verify(sp800SecureRandom).nextBytes(bytes); } }