private void doHashTest(int index, DRBGTestVector tv) { SP800SecureRandomBuilder rBuild = new SP800SecureRandomBuilder(new SHA1EntropyProvider()); rBuild.setPersonalizationString(tv.personalizationString()); rBuild.setSecurityStrength(tv.securityStrength()); rBuild.setEntropyBitsRequired(tv.entropySource().getEntropy().length * 8); SecureRandom random = rBuild.buildHash(tv.getDigest(), tv.nonce(), tv.predictionResistance()); byte[] expected = tv.expectedValue(0); byte[] produced = new byte[expected.length]; random.nextBytes(produced); if (!Arrays.areEqual(expected, produced)) { fail(index + " SP800 Hash SecureRandom produced incorrect result (1)"); } random.nextBytes(produced); expected = tv.expectedValue(1); if (!Arrays.areEqual(expected, produced)) { fail(index + " SP800 Hash SecureRandom produced incorrect result (2)"); } }
private void doHMACTest(DRBGTestVector tv) { SP800SecureRandomBuilder rBuild = new SP800SecureRandomBuilder(new SHA1EntropyProvider()); rBuild.setPersonalizationString(tv.personalizationString()); rBuild.setSecurityStrength(tv.securityStrength()); rBuild.setEntropyBitsRequired(tv.entropySource().getEntropy().length * 8); SecureRandom random = rBuild.buildHMAC(new HMac(tv.getDigest()), tv.nonce(), tv.predictionResistance()); byte[] expected = tv.expectedValue(0); byte[] produced = new byte[expected.length]; random.nextBytes(produced); if (!Arrays.areEqual(expected, produced)) { fail("SP800 HMAC SecureRandom produced incorrect result (1)"); } random.nextBytes(produced); expected = tv.expectedValue(1); if (!Arrays.areEqual(expected, produced)) { fail("SP800 HMAC SecureRandom produced incorrect result (2)"); } }
private void doDualECTest(int index, DRBGTestVector tv) { SP800SecureRandomBuilder rBuild = new SP800SecureRandomBuilder(new SHA256EntropyProvider()); rBuild.setPersonalizationString(tv.personalizationString()); rBuild.setSecurityStrength(tv.securityStrength()); rBuild.setEntropyBitsRequired(tv.securityStrength()); SecureRandom random = rBuild.buildDualEC(tv.getDigest(), tv.nonce(), tv.predictionResistance()); byte[] expected = tv.expectedValue(0); byte[] produced = new byte[expected.length]; random.nextBytes(produced); if (!Arrays.areEqual(expected, produced)) { fail(index + " SP800 Dual EC SecureRandom produced incorrect result (1)"); } random.nextBytes(produced); expected = tv.expectedValue(1); if (!Arrays.areEqual(expected, produced)) { fail(index + " SP800 Dual EC SecureRandom produced incorrect result (2)"); } }
private void doCTRTest(DRBGTestVector tv) { SP800SecureRandomBuilder rBuild = new SP800SecureRandomBuilder(new Bit232EntropyProvider()); rBuild.setPersonalizationString(tv.personalizationString()); rBuild.setSecurityStrength(tv.securityStrength()); rBuild.setEntropyBitsRequired(tv.entropySource().getEntropy().length * 8); SecureRandom random = rBuild.buildCTR(tv.getCipher(), tv.keySizeInBits(), tv.nonce(), tv.predictionResistance()); byte[] expected = tv.expectedValue(0); byte[] produced = new byte[expected.length]; random.nextBytes(produced); if (!Arrays.areEqual(expected, produced)) { fail("SP800 CTR SecureRandom produced incorrect result (1)"); } random.nextBytes(produced); expected = tv.expectedValue(1); if (!Arrays.areEqual(expected, produced)) { fail("SP800 CTR SecureRandom produced incorrect result (2)"); } }
/** * Generates a deterministic SecureRandom based on the userKey and serverKey. */ public static SecureRandom getSecureRandom(byte[] userKey, byte[] serverKey) { SecureRandom secureRandom; try { secureRandom = SecureRandom.getInstance(RANDOM_NUMBER_ALGORITHM, RANDOM_NUMBER_ALGORITHM_PROVIDER); } catch (Exception e) { LOGGER.error(null, e); secureRandom = new SecureRandom(); } byte[] userSeed = new byte[Math.max(userKey.length, serverKey.length)]; // XOR the key parts to get our seed, repeating them if they lengths // don't match for (int i = 0; i < userSeed.length; i++) { userSeed[i] = (byte) (userKey[i % userKey.length] ^ serverKey[i % serverKey.length]); } // Set up out private key variables secureRandom.setSeed(userSeed); final SecureRandom finalSecureRandom = secureRandom; SP800SecureRandomBuilder sp800SecureRandomBuilder = new SP800SecureRandomBuilder(i -> new EntropySource() { @Override public boolean isPredictionResistant() { return true; } @Override public byte[] getEntropy() { byte[] entropy = new byte[(i + 7) / 8]; finalSecureRandom.nextBytes(entropy); return entropy; } @Override public int entropySize() { return i; } }); sp800SecureRandomBuilder.setPersonalizationString(userKey); secureRandom = sp800SecureRandomBuilder.buildHash(new SHA512Digest(), serverKey, true); return secureRandom; }