diff --git a/briar-api/src/org/briarproject/api/crypto/SeedProvider.java b/briar-api/src/org/briarproject/api/crypto/SeedProvider.java
new file mode 100644
index 0000000000000000000000000000000000000000..56cc9092a230f71034f63365054beb0109b0211a
--- /dev/null
+++ b/briar-api/src/org/briarproject/api/crypto/SeedProvider.java
@@ -0,0 +1,12 @@
+package org.briarproject.api.crypto;
+
+/**
+ * Uses a platform-specific source to provide a seed for a pseudo-random
+ * number generator.
+ */
+public interface SeedProvider {
+
+	int SEED_BYTES = 32;
+
+	byte[] getSeed();
+}
diff --git a/briar-core/src/org/briarproject/crypto/CryptoComponentImpl.java b/briar-core/src/org/briarproject/crypto/CryptoComponentImpl.java
index 4f689f463550c466ebc5ec578a809577d91bbcdd..e6d7c3cdbf97a2024f9a4ea82cdd1fc93dc00f03 100644
--- a/briar-core/src/org/briarproject/crypto/CryptoComponentImpl.java
+++ b/briar-core/src/org/briarproject/crypto/CryptoComponentImpl.java
@@ -19,6 +19,8 @@ import java.util.Collections;
 import java.util.List;
 import java.util.logging.Logger;
 
+import javax.inject.Inject;
+
 import org.briarproject.api.crypto.AuthenticatedCipher;
 import org.briarproject.api.crypto.CryptoComponent;
 import org.briarproject.api.crypto.KeyPair;
@@ -28,9 +30,9 @@ import org.briarproject.api.crypto.PrivateKey;
 import org.briarproject.api.crypto.PseudoRandom;
 import org.briarproject.api.crypto.PublicKey;
 import org.briarproject.api.crypto.SecretKey;
+import org.briarproject.api.crypto.SeedProvider;
 import org.briarproject.api.crypto.Signature;
 import org.briarproject.util.ByteUtils;
-
 import org.spongycastle.crypto.AsymmetricCipherKeyPair;
 import org.spongycastle.crypto.BlockCipher;
 import org.spongycastle.crypto.CipherParameters;
@@ -86,23 +88,25 @@ class CryptoComponentImpl implements CryptoComponent {
 	// Blank secret for argument validation
 	private static final byte[] BLANK_SECRET = new byte[CIPHER_KEY_BYTES];
 
-	private final KeyParser agreementKeyParser, signatureKeyParser;
 	private final SecureRandom secureRandom;
 	private final ECKeyPairGenerator agreementKeyPairGenerator;
 	private final ECKeyPairGenerator signatureKeyPairGenerator;
+	private final KeyParser agreementKeyParser, signatureKeyParser;
 
-	CryptoComponentImpl() {
-		agreementKeyParser = new Sec1KeyParser(PARAMETERS, P,
-				AGREEMENT_KEY_PAIR_BITS);
-		signatureKeyParser = new Sec1KeyParser(PARAMETERS, P,
-				SIGNATURE_KEY_PAIR_BITS);
-		secureRandom = new SecureRandom();
+	@Inject
+	CryptoComponentImpl(SeedProvider r) {
+		if(!FortunaSecureRandom.selfTest()) throw new RuntimeException();
+		secureRandom = new FortunaSecureRandom(r.getSeed());
 		ECKeyGenerationParameters params = new ECKeyGenerationParameters(
 				PARAMETERS, secureRandom);
 		agreementKeyPairGenerator = new ECKeyPairGenerator();
 		agreementKeyPairGenerator.init(params);
 		signatureKeyPairGenerator = new ECKeyPairGenerator();
 		signatureKeyPairGenerator.init(params);
+		agreementKeyParser = new Sec1KeyParser(PARAMETERS, P,
+				AGREEMENT_KEY_PAIR_BITS);
+		signatureKeyParser = new Sec1KeyParser(PARAMETERS, P,
+				SIGNATURE_KEY_PAIR_BITS);
 	}
 
 	public SecretKey generateSecretKey() {
diff --git a/briar-core/src/org/briarproject/crypto/CryptoModule.java b/briar-core/src/org/briarproject/crypto/CryptoModule.java
index f0eb56f05dbb57c04238392f19c9c7d8162a247e..9d097e7e82ca2e6216549ecc6feba2d0bdd1ca71 100644
--- a/briar-core/src/org/briarproject/crypto/CryptoModule.java
+++ b/briar-core/src/org/briarproject/crypto/CryptoModule.java
@@ -14,7 +14,9 @@ import javax.inject.Singleton;
 import org.briarproject.api.crypto.CryptoComponent;
 import org.briarproject.api.crypto.CryptoExecutor;
 import org.briarproject.api.crypto.PasswordStrengthEstimator;
+import org.briarproject.api.crypto.SeedProvider;
 import org.briarproject.api.lifecycle.LifecycleManager;
+import org.briarproject.util.OsUtils;
 
 import com.google.inject.AbstractModule;
 import com.google.inject.Provides;
@@ -39,6 +41,9 @@ public class CryptoModule extends AbstractModule {
 	}
 
 	protected void configure() {
+		if(OsUtils.isAndroid() || OsUtils.isLinux()) {
+			bind(SeedProvider.class).to(LinuxSeedProvider.class);
+		}
 		bind(CryptoComponent.class).to(
 				CryptoComponentImpl.class).in(Singleton.class);
 		bind(PasswordStrengthEstimator.class).to(
diff --git a/briar-core/src/org/briarproject/crypto/FortunaGenerator.java b/briar-core/src/org/briarproject/crypto/FortunaGenerator.java
new file mode 100644
index 0000000000000000000000000000000000000000..48cf66e5fddfda2fdef5560d435cf9ae62246aa9
--- /dev/null
+++ b/briar-core/src/org/briarproject/crypto/FortunaGenerator.java
@@ -0,0 +1,83 @@
+package org.briarproject.crypto;
+
+import org.briarproject.api.crypto.MessageDigest;
+import org.spongycastle.crypto.BlockCipher;
+import org.spongycastle.crypto.digests.SHA256Digest;
+import org.spongycastle.crypto.engines.AESLightEngine;
+import org.spongycastle.crypto.params.KeyParameter;
+
+/**
+ * Implements the Fortuna pseudo-random number generator, as described in
+ * Ferguson and Schneier, <i>Practical Cryptography</i>, chapter 9.
+ */
+class FortunaGenerator {
+
+	private static final int MAX_BYTES_PER_REQUEST = 1024 * 1024;
+	private static final int KEY_BYTES = 32;
+	private static final int BLOCK_BYTES = 16;
+
+	// All of the following are locking: this
+	private final MessageDigest digest = new DoubleDigest(new SHA256Digest());
+	private final BlockCipher cipher = new AESLightEngine();
+	private final byte[] key = new byte[KEY_BYTES];
+	private final byte[] counter = new byte[BLOCK_BYTES];
+	private final byte[] buffer = new byte[BLOCK_BYTES];
+	private final byte[] newKey = new byte[KEY_BYTES];
+
+	FortunaGenerator(byte[] seed) {
+		reseed(seed);
+	}
+
+	synchronized void reseed(byte[] seed) {
+		digest.update(key);
+		digest.update(seed);
+		digest.digest(key, 0, KEY_BYTES);
+		incrementCounter();
+	}
+
+	// Package access for testing
+	synchronized void incrementCounter() {
+		counter[0]++;
+		for(int i = 0; counter[i] == 0; i++) {
+			if(i + 1 == BLOCK_BYTES)
+				throw new RuntimeException("Counter exhausted");
+			counter[i + 1]++;
+		}
+	}
+
+	// Package access for testing
+	synchronized byte[] getCounter() {
+		return counter;
+	}
+
+	synchronized int nextBytes(byte[] dest, int off, int len) {
+		// Don't write more than the maximum number of bytes in one request
+		if(len > MAX_BYTES_PER_REQUEST) len = MAX_BYTES_PER_REQUEST;
+		cipher.init(true, new KeyParameter(key));
+		// Generate full blocks directly into the output buffer
+		int fullBlocks = len / BLOCK_BYTES;
+		for(int i = 0; i < fullBlocks; i++) {
+			cipher.processBlock(counter, 0, dest, off + i * BLOCK_BYTES);
+			incrementCounter();
+		}
+		// Generate a partial block if needed
+		int done = fullBlocks * BLOCK_BYTES, remaining = len - done;
+		assert remaining < BLOCK_BYTES;
+		if(remaining > 0) {
+			cipher.processBlock(counter, 0, buffer, 0);
+			incrementCounter();
+			// Copy the partial block to the output buffer and erase our copy
+			System.arraycopy(buffer, 0, dest, off + done, remaining);
+			for(int i = 0; i < BLOCK_BYTES; i++) buffer[i] = 0;
+		}
+		// Generate a new key
+		for(int i = 0; i < KEY_BYTES / BLOCK_BYTES; i++) {
+			cipher.processBlock(counter, 0, newKey, i * BLOCK_BYTES);
+			incrementCounter();
+		}
+		System.arraycopy(newKey, 0, key, 0, KEY_BYTES);
+		for(int i = 0; i < KEY_BYTES; i++) newKey[i] = 0;
+		// Return the number of bytes written
+		return len;
+	}
+}
diff --git a/briar-core/src/org/briarproject/crypto/FortunaSecureRandom.java b/briar-core/src/org/briarproject/crypto/FortunaSecureRandom.java
new file mode 100644
index 0000000000000000000000000000000000000000..01f7057e22a15771235c67bd6235b2fa9655f851
--- /dev/null
+++ b/briar-core/src/org/briarproject/crypto/FortunaSecureRandom.java
@@ -0,0 +1,87 @@
+package org.briarproject.crypto;
+
+import java.security.Provider;
+import java.security.SecureRandom;
+import java.security.SecureRandomSpi;
+import java.util.Arrays;
+
+import org.briarproject.util.StringUtils;
+
+/**
+ * A {@link java.security.SecureRandom SecureRandom} implementation based on a
+ * {@link FortunaGenerator}.
+ */
+class FortunaSecureRandom extends SecureRandom {
+
+	// Package access for testing
+	static final byte[] SELF_TEST_VECTOR_1 =
+			StringUtils.fromHexString("4BD6EA599D47E3EE9DD911833C29CA22");
+	static final byte[] SELF_TEST_VECTOR_2 =
+			StringUtils.fromHexString("10984D576E6850E505CA9F42A9BFD88A");
+	static final byte[] SELF_TEST_VECTOR_3 =
+			StringUtils.fromHexString("1E12DA166BD86DCECDE50A8296018DE2");
+
+	private static final long serialVersionUID = -417332227850184134L;
+	private static final Provider PROVIDER = new FortunaProvider();
+
+	FortunaSecureRandom(byte[] seed) {
+		super(new FortunaSecureRandomSpi(seed), PROVIDER);
+	}
+
+	/**
+	 * Tests that the {@link #nextBytes(byte[])} and {@link #setSeed(byte[])}
+	 * methods are passed through to the generator in the expected way.
+	 */
+	static boolean selfTest() {
+		byte[] seed = new byte[32];
+		SecureRandom r = new FortunaSecureRandom(seed);
+		byte[] output = new byte[16];
+		r.nextBytes(output);
+		if(!Arrays.equals(SELF_TEST_VECTOR_1, output)) return false;
+		r.nextBytes(output);
+		if(!Arrays.equals(SELF_TEST_VECTOR_2, output)) return false;
+		r.setSeed(seed);
+		r.nextBytes(output);
+		if(!Arrays.equals(SELF_TEST_VECTOR_3, output)) return false;
+		return true;
+	}
+
+	private static class FortunaSecureRandomSpi extends SecureRandomSpi {
+
+		private static final long serialVersionUID = -1677799887497202351L;
+
+		private final FortunaGenerator generator;
+
+		private FortunaSecureRandomSpi(byte[] seed) {
+			generator = new FortunaGenerator(seed);
+		}
+
+		@Override
+		protected byte[] engineGenerateSeed(int numBytes) {
+			byte[] b = new byte[numBytes];
+			engineNextBytes(b);
+			return b;
+		}
+
+		@Override
+		protected void engineNextBytes(byte[] b) {
+			int offset = 0;
+			while(offset < b.length)
+				offset += generator.nextBytes(b, offset, b.length - offset);
+		}
+
+		@Override
+		protected void engineSetSeed(byte[] seed) {
+			generator.reseed(seed);
+		}
+	}
+
+	private static class FortunaProvider extends Provider {
+
+		private static final long serialVersionUID = -833121797778381769L;
+
+		private FortunaProvider() {
+			super("Fortuna", 1.0, "");
+		}
+	}
+}
diff --git a/briar-core/src/org/briarproject/crypto/LinuxSeedProvider.java b/briar-core/src/org/briarproject/crypto/LinuxSeedProvider.java
new file mode 100644
index 0000000000000000000000000000000000000000..3db1cd87f502ced42e64f1b1d1bf85ec2913fdac
--- /dev/null
+++ b/briar-core/src/org/briarproject/crypto/LinuxSeedProvider.java
@@ -0,0 +1,23 @@
+package org.briarproject.crypto;
+
+import java.io.DataInputStream;
+import java.io.FileInputStream;
+import java.io.IOException;
+
+import org.briarproject.api.crypto.SeedProvider;
+
+class LinuxSeedProvider implements SeedProvider {
+
+	public byte[] getSeed() {
+		byte[] seed = new byte[SEED_BYTES];
+		try {
+			DataInputStream in =  new DataInputStream(
+					new FileInputStream("/dev/urandom"));
+			in.readFully(seed);
+			in.close();
+		} catch(IOException e) {
+			throw new RuntimeException(e);
+		}
+		return seed;
+	}
+}
diff --git a/briar-tests/.classpath b/briar-tests/.classpath
index 8905224944fdbb1e3d566e87a215fc23148793ec..4d9d92d61c046fc519c4260e804a197afb1d495e 100644
--- a/briar-tests/.classpath
+++ b/briar-tests/.classpath
@@ -12,5 +12,6 @@
 	<classpathentry kind="lib" path="libs/jmock-2.5.1.jar"/>
 	<classpathentry kind="lib" path="libs/junit-4.9b3.jar"/>
 	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6"/>
+	<classpathentry kind="lib" path="/briar-core/libs/sc-light-jdk15on-1.47.0.3-SNAPSHOT.jar" sourcepath="/briar-core/libs/source/sc-light-jdk15on-1.47.0.3-SNAPSHOT-source.jar"/>
 	<classpathentry kind="output" path="bin"/>
 </classpath>
diff --git a/briar-tests/build.xml b/briar-tests/build.xml
index 898d2c627ea8e54aba411869f9f59b67dd5dbf56..01eca558d3416f42c8910407b93f6723d3d3304d 100644
--- a/briar-tests/build.xml
+++ b/briar-tests/build.xml
@@ -93,6 +93,8 @@
 			<jvmarg value='-Djava.library.path=../briar-desktop/libs'/>
 			<test name='org.briarproject.LockFairnessTest'/>
 			<test name='org.briarproject.ProtocolIntegrationTest'/>
+			<test name='org.briarproject.crypto.FortunaGeneratorTest'/>
+			<test name='org.briarproject.crypto.FortunaSecureRandomTest'/>
 			<test name='org.briarproject.crypto.KeyAgreementTest'/>
 			<test name='org.briarproject.crypto.KeyDerivationTest'/>
 			<test name='org.briarproject.crypto.KeyEncodingAndParsingTest'/>
diff --git a/briar-tests/src/org/briarproject/TestSeedProvider.java b/briar-tests/src/org/briarproject/TestSeedProvider.java
new file mode 100644
index 0000000000000000000000000000000000000000..6a6ef90d91307fb404405e9df607b24eb52ddc28
--- /dev/null
+++ b/briar-tests/src/org/briarproject/TestSeedProvider.java
@@ -0,0 +1,16 @@
+package org.briarproject;
+
+import java.util.Random;
+
+import org.briarproject.api.crypto.SeedProvider;
+
+public class TestSeedProvider implements SeedProvider {
+
+	private final Random random = new Random();
+
+	public byte[] getSeed() {
+		byte[] seed = new byte[32];
+		random.nextBytes(seed);
+		return seed;
+	}
+}
diff --git a/briar-tests/src/org/briarproject/crypto/FortunaGeneratorTest.java b/briar-tests/src/org/briarproject/crypto/FortunaGeneratorTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..fe083489aafbeedb19deae488eea1731b6c939ca
--- /dev/null
+++ b/briar-tests/src/org/briarproject/crypto/FortunaGeneratorTest.java
@@ -0,0 +1,98 @@
+package org.briarproject.crypto;
+
+import static org.junit.Assert.assertArrayEquals;
+
+import org.briarproject.BriarTestCase;
+import org.junit.Test;
+import org.spongycastle.crypto.BlockCipher;
+import org.spongycastle.crypto.engines.AESLightEngine;
+import org.spongycastle.crypto.params.KeyParameter;
+
+public class FortunaGeneratorTest extends BriarTestCase {
+
+	@Test
+	public void testCounterInitialisedToOne() {
+		FortunaGenerator f = new FortunaGenerator(new byte[32]);
+		// The counter is little-endian
+		byte[] expected = new byte[16];
+		expected[0] = 1;
+		assertArrayEquals(expected, f.getCounter());
+	}
+
+	@Test
+	public void testIncrementCounter() {
+		FortunaGenerator f = new FortunaGenerator(new byte[32]);
+		// Increment the counter until it reaches 255
+		for(int i = 1; i < 255; i++) f.incrementCounter();
+		byte[] expected = new byte[16];
+		expected[0] = (byte) 255;
+		assertArrayEquals(expected, f.getCounter());
+		// Increment the counter again - it should carry into the next byte
+		f.incrementCounter();
+		expected[0] = 0;
+		expected[1] = 1;
+		assertArrayEquals(expected, f.getCounter());
+		// Increment the counter until it carries into the next byte
+		for(int i = 256; i < 65536; i++) f.incrementCounter();
+		expected[0] = 0;
+		expected[1] = 0;
+		expected[2] = 1;
+		assertArrayEquals(expected, f.getCounter());
+	}
+
+	@Test
+	public void testNextBytes() {
+		// Generate several outputs with the same seed - they should all match
+		byte[] seed = new byte[32];
+		byte[] out1 = new byte[48];
+		new FortunaGenerator(seed).nextBytes(out1, 0, 48);
+		// One byte longer than a block, with an offset of one
+		byte[] out2 = new byte[49];
+		new FortunaGenerator(seed).nextBytes(out2, 1, 48);
+		for(int i = 0; i < 48; i++) assertEquals(out1[i], out2[i + 1]);
+		// One byte shorter than a block
+		byte[] out3 = new byte[47];
+		new FortunaGenerator(seed).nextBytes(out3, 0, 47);
+		for(int i = 0; i < 47; i++) assertEquals(out1[i], out3[i]);
+		// Less than a block, with an offset greater than a block
+		byte[] out4 = new byte[32];
+		new FortunaGenerator(seed).nextBytes(out4, 17, 15);
+		for(int i = 0; i < 15; i++) assertEquals(out1[i], out4[i + 17]);
+	}
+
+	@Test
+	public void testRekeying() {
+		byte[] seed = new byte[32];
+		FortunaGenerator f = new FortunaGenerator(seed);
+		// Generate three blocks of output
+		byte[] out1 = new byte[48];
+		f.nextBytes(out1, 0, 48);
+		// Create another generator with the same seed and generate one block
+		f = new FortunaGenerator(seed);
+		byte[] out2 = new byte[16];
+		f.nextBytes(out2, 0, 16);
+		// The generator should have rekeyed with the 2nd and 3rd blocks
+		byte[] expectedKey = new byte[32];
+		System.arraycopy(out1, 16, expectedKey, 0, 32);
+		// The generator's counter should have been incremented 3 times
+		byte[] expectedCounter = new byte[16];
+		expectedCounter[0] = 4;
+		// The next expected output block is the counter encrypted with the key
+		byte[] expectedOutput = new byte[16];
+		BlockCipher c = new AESLightEngine();
+		c.init(true, new KeyParameter(expectedKey));
+		c.processBlock(expectedCounter, 0, expectedOutput, 0);
+		// Check that the generator produces the expected output block
+		byte[] out3 = new byte[16];
+		f.nextBytes(out3, 0, 16);
+		assertArrayEquals(expectedOutput, out3);
+	}
+
+	@Test
+	public void testMaximumRequestLength() {
+		int expectedMax = 1024 * 1024;
+		byte[] output = new byte[expectedMax + 123];
+		FortunaGenerator f = new FortunaGenerator(new byte[32]);
+		assertEquals(expectedMax, f.nextBytes(output, 0, output.length));
+	}
+}
diff --git a/briar-tests/src/org/briarproject/crypto/FortunaSecureRandomTest.java b/briar-tests/src/org/briarproject/crypto/FortunaSecureRandomTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..b464729f31fb3e8a03bae5f06806232abea50414
--- /dev/null
+++ b/briar-tests/src/org/briarproject/crypto/FortunaSecureRandomTest.java
@@ -0,0 +1,67 @@
+package org.briarproject.crypto;
+
+import static org.briarproject.crypto.FortunaSecureRandom.SELF_TEST_VECTOR_1;
+import static org.briarproject.crypto.FortunaSecureRandom.SELF_TEST_VECTOR_2;
+import static org.briarproject.crypto.FortunaSecureRandom.SELF_TEST_VECTOR_3;
+import static org.junit.Assert.assertArrayEquals;
+
+import org.briarproject.BriarTestCase;
+import org.briarproject.api.crypto.MessageDigest;
+import org.junit.Test;
+import org.spongycastle.crypto.BlockCipher;
+import org.spongycastle.crypto.digests.SHA256Digest;
+import org.spongycastle.crypto.engines.AESLightEngine;
+import org.spongycastle.crypto.params.KeyParameter;
+
+public class FortunaSecureRandomTest extends BriarTestCase {
+
+	@Test
+	public void testClassPassesSelfTest() {
+		assertTrue(FortunaSecureRandom.selfTest());
+	}
+
+	@Test
+	public void testSelfTestVectorsAreReproducible() {
+		byte[] key = new byte[32], seed = new byte[32];
+		byte[] counter = new byte[16], output = new byte[16];
+		byte[] newKey = new byte[32];
+		// Calculate the initial key
+		MessageDigest digest = new DoubleDigest(new SHA256Digest());
+		digest.update(key);
+		digest.update(seed);
+		digest.digest(key, 0, 32);
+		// Calculate the first output block and the new key
+		BlockCipher c = new AESLightEngine();
+		c.init(true, new KeyParameter(key));
+		counter[0] = 1;
+		c.processBlock(counter, 0, output, 0);
+		counter[0] = 2;
+		c.processBlock(counter, 0, newKey, 0);
+		counter[0] = 3;
+		c.processBlock(counter, 0, newKey, 16);
+		System.arraycopy(newKey, 0, key, 0, 32);
+		// The first self-test vector should match the first output block
+		assertArrayEquals(SELF_TEST_VECTOR_1, output);
+		// Calculate the second output block and the new key before reseeding
+		c.init(true, new KeyParameter(key));
+		counter[0] = 4;
+		c.processBlock(counter, 0, output, 0);
+		counter[0] = 5;
+		c.processBlock(counter, 0, newKey, 0);
+		counter[0] = 6;
+		c.processBlock(counter, 0, newKey, 16);
+		System.arraycopy(newKey, 0, key, 0, 32);
+		// The second self-test vector should match the second output block
+		assertArrayEquals(SELF_TEST_VECTOR_2, output);
+		// Calculate the new key after reseeding
+		digest.update(key);
+		digest.update(seed);
+		digest.digest(key, 0, 32);
+		// Calculate the third output block
+		c.init(true, new KeyParameter(key));
+		counter[0] = 8;
+		c.processBlock(counter, 0, output, 0);
+		// The third self-test vector should match the third output block
+		assertArrayEquals(SELF_TEST_VECTOR_3, output);
+	}
+}
diff --git a/briar-tests/src/org/briarproject/crypto/KeyAgreementTest.java b/briar-tests/src/org/briarproject/crypto/KeyAgreementTest.java
index 33b7f4a9874d6da3ab12a9e828afc403c7f608c7..1193e60d950977c53b3f13e78c5b8f8d2ff87ba4 100644
--- a/briar-tests/src/org/briarproject/crypto/KeyAgreementTest.java
+++ b/briar-tests/src/org/briarproject/crypto/KeyAgreementTest.java
@@ -1,17 +1,20 @@
 package org.briarproject.crypto;
 
 import static org.junit.Assert.assertArrayEquals;
+
 import org.briarproject.BriarTestCase;
+import org.briarproject.TestSeedProvider;
 import org.briarproject.api.crypto.CryptoComponent;
 import org.briarproject.api.crypto.KeyPair;
-
+import org.briarproject.api.crypto.SeedProvider;
 import org.junit.Test;
 
 public class KeyAgreementTest extends BriarTestCase {
 
 	@Test
 	public void testKeyAgreement() throws Exception {
-		CryptoComponent crypto = new CryptoComponentImpl();
+		SeedProvider seedProvider = new TestSeedProvider();
+		CryptoComponent crypto = new CryptoComponentImpl(seedProvider);
 		KeyPair aPair = crypto.generateAgreementKeyPair();
 		byte[] aPub = aPair.getPublic().getEncoded();
 		KeyPair bPair = crypto.generateAgreementKeyPair();
diff --git a/briar-tests/src/org/briarproject/crypto/KeyDerivationTest.java b/briar-tests/src/org/briarproject/crypto/KeyDerivationTest.java
index 00d7bdda80a931bd69136baff15f84656cba3209..d2c02c078aef2a11dada6f80e868ccf540d36096 100644
--- a/briar-tests/src/org/briarproject/crypto/KeyDerivationTest.java
+++ b/briar-tests/src/org/briarproject/crypto/KeyDerivationTest.java
@@ -6,9 +6,9 @@ import java.util.List;
 import java.util.Random;
 
 import org.briarproject.BriarTestCase;
+import org.briarproject.TestSeedProvider;
 import org.briarproject.api.crypto.CryptoComponent;
 import org.briarproject.api.crypto.SecretKey;
-
 import org.junit.Test;
 
 public class KeyDerivationTest extends BriarTestCase {
@@ -17,7 +17,7 @@ public class KeyDerivationTest extends BriarTestCase {
 	private final byte[] secret;
 
 	public KeyDerivationTest() {
-		crypto = new CryptoComponentImpl();
+		crypto = new CryptoComponentImpl(new TestSeedProvider());
 		secret = new byte[32];
 		new Random().nextBytes(secret);
 	}
diff --git a/briar-tests/src/org/briarproject/crypto/KeyEncodingAndParsingTest.java b/briar-tests/src/org/briarproject/crypto/KeyEncodingAndParsingTest.java
index 63601b002d28ec7755022e1091040d871c332630..a4d8e7b78f0d3fc2bb9c38193d29df7d00b0ba91 100644
--- a/briar-tests/src/org/briarproject/crypto/KeyEncodingAndParsingTest.java
+++ b/briar-tests/src/org/briarproject/crypto/KeyEncodingAndParsingTest.java
@@ -6,6 +6,7 @@ import java.security.GeneralSecurityException;
 import java.util.Random;
 
 import org.briarproject.BriarTestCase;
+import org.briarproject.TestSeedProvider;
 import org.briarproject.api.crypto.KeyPair;
 import org.briarproject.api.crypto.KeyParser;
 import org.briarproject.api.crypto.PrivateKey;
@@ -15,7 +16,8 @@ import org.junit.Test;
 
 public class KeyEncodingAndParsingTest extends BriarTestCase {
 
-	private final CryptoComponentImpl crypto = new CryptoComponentImpl();
+	private final CryptoComponentImpl crypto =
+			new CryptoComponentImpl(new TestSeedProvider());
 
 	@Test
 	public void testAgreementPublicKeyEncodingAndParsing() throws Exception {
diff --git a/briar-tests/src/org/briarproject/crypto/PasswordBasedKdfTest.java b/briar-tests/src/org/briarproject/crypto/PasswordBasedKdfTest.java
index dda28810034ba64a0787bfff9b39bce2abbfd399..44dd617e51cc5cfb90a41e139d7fba6f07a9d379 100644
--- a/briar-tests/src/org/briarproject/crypto/PasswordBasedKdfTest.java
+++ b/briar-tests/src/org/briarproject/crypto/PasswordBasedKdfTest.java
@@ -5,15 +5,16 @@ import static org.junit.Assert.assertArrayEquals;
 import java.util.Random;
 
 import org.briarproject.BriarTestCase;
-import org.briarproject.api.crypto.CryptoComponent;
-
+import org.briarproject.TestSeedProvider;
 import org.junit.Test;
 
 public class PasswordBasedKdfTest extends BriarTestCase {
 
+	private final CryptoComponentImpl crypto =
+			new CryptoComponentImpl(new TestSeedProvider());
+
 	@Test
 	public void testEncryptionAndDecryption() {
-		CryptoComponent crypto = new CryptoComponentImpl();
 		Random random = new Random();
 		byte[] input = new byte[1234];
 		random.nextBytes(input);
@@ -25,7 +26,6 @@ public class PasswordBasedKdfTest extends BriarTestCase {
 
 	@Test
 	public void testInvalidCiphertextReturnsNull() {
-		CryptoComponent crypto = new CryptoComponentImpl();
 		Random random = new Random();
 		byte[] input = new byte[1234];
 		random.nextBytes(input);
@@ -41,7 +41,6 @@ public class PasswordBasedKdfTest extends BriarTestCase {
 
 	@Test
 	public void testCalibration() {
-		CryptoComponentImpl crypto = new CryptoComponentImpl();
 		// If the target time is unachievable, one iteration should be used
 		int iterations = crypto.chooseIterationCount(0);
 		assertEquals(1, iterations);