diff --git a/api/net/sf/briar/api/crypto/CryptoComponent.java b/api/net/sf/briar/api/crypto/CryptoComponent.java
index 83e5da292edb7899e763ebe3a3e649be76bf6423..c6e4b34fd9fc52d7439e819cdd58367eb906aa43 100644
--- a/api/net/sf/briar/api/crypto/CryptoComponent.java
+++ b/api/net/sf/briar/api/crypto/CryptoComponent.java
@@ -53,6 +53,10 @@ public interface CryptoComponent {
 	 */
 	byte[] deriveNextSecret(byte[] secret, long period);
 
+	/** Encodes the pseudo-random tag that is used to recognise a connection. */
+	void encodeTag(byte[] tag, Cipher tagCipher, ErasableKey tagKey,
+			long connection);
+
 	KeyPair generateAgreementKeyPair();
 
 	KeyPair generateSignatureKeyPair();
diff --git a/api/net/sf/briar/api/db/TemporarySecret.java b/api/net/sf/briar/api/db/TemporarySecret.java
index e3818b14e5c971f0c735d7a4468962b10d4618e0..db2aa95dc78a2bfd4c5693f1809f9ff52ebbd9cb 100644
--- a/api/net/sf/briar/api/db/TemporarySecret.java
+++ b/api/net/sf/briar/api/db/TemporarySecret.java
@@ -9,6 +9,7 @@ public class TemporarySecret extends ContactTransport {
 	private final long period, outgoing, centre;
 	private final byte[] secret, bitmap;
 
+	/** Creates a temporary secret with the given connection window. */
 	public TemporarySecret(ContactId contactId, TransportId transportId,
 			long epoch, long clockDiff, long latency, boolean alice,
 			long period, byte[] secret, long outgoing, long centre,
@@ -21,14 +22,19 @@ public class TemporarySecret extends ContactTransport {
 		this.bitmap = bitmap;
 	}
 
+	/** Creates a temporary secret with a new connection window. */
+	public TemporarySecret(ContactId contactId, TransportId transportId,
+			long epoch, long clockDiff, long latency, boolean alice,
+			long period, byte[] secret) {
+		this(contactId, transportId, epoch, clockDiff, latency, alice, period,
+				secret, 0L, 0L, new byte[CONNECTION_WINDOW_SIZE / 8]);
+	}
+
+	/** Creates a temporary secret derived from the given temporary secret. */
 	public TemporarySecret(TemporarySecret old, long period, byte[] secret) {
-		super(old.getContactId(), old.getTransportId(), old.getEpoch(),
-				old.getClockDifference(), old.getLatency(), old.getAlice());
-		this.period = period;
-		this.secret = secret;
-		outgoing = 0L;
-		centre = 0L;
-		bitmap = new byte[CONNECTION_WINDOW_SIZE / 8];
+		this(old.getContactId(), old.getTransportId(), old.getEpoch(),
+				old.getClockDifference(), old.getLatency(), old.getAlice(),
+				period, secret);
 	}
 
 	public long getPeriod() {
diff --git a/api/net/sf/briar/api/transport/ConnectionReaderFactory.java b/api/net/sf/briar/api/transport/ConnectionReaderFactory.java
index 9d7f7d4b580363534fe8bb767d5d7b6f2baddd52..148e07256ad14effbb0bb2daafd7e09f1f78feb4 100644
--- a/api/net/sf/briar/api/transport/ConnectionReaderFactory.java
+++ b/api/net/sf/briar/api/transport/ConnectionReaderFactory.java
@@ -8,5 +8,5 @@ public interface ConnectionReaderFactory {
 	 * Creates a connection reader for one side of a connection.
 	 */
 	ConnectionReader createConnectionReader(InputStream in,
-			ConnectionContext ctx, boolean initiator);
+			ConnectionContext ctx, boolean incoming, boolean initiator);
 }
diff --git a/api/net/sf/briar/api/transport/ConnectionWriterFactory.java b/api/net/sf/briar/api/transport/ConnectionWriterFactory.java
index 452cbeba6db71a42c55cd9b0026280a89f7f28ce..217d2ec8113c9713aec15ef0c2fcc0b481224966 100644
--- a/api/net/sf/briar/api/transport/ConnectionWriterFactory.java
+++ b/api/net/sf/briar/api/transport/ConnectionWriterFactory.java
@@ -8,5 +8,5 @@ public interface ConnectionWriterFactory {
 	 * Creates a connection writer for one side of a connection.
 	 */
 	ConnectionWriter createConnectionWriter(OutputStream out, long capacity,
-			ConnectionContext ctx, boolean initiator);
+			ConnectionContext ctx, boolean incoming, boolean initiator);
 }
diff --git a/components/net/sf/briar/crypto/CryptoComponentImpl.java b/components/net/sf/briar/crypto/CryptoComponentImpl.java
index 58a7a1e5cba835c5ad149e929da1303866b4d49b..bc1c07a53f6ead71c77c1c98632e0619a443a921 100644
--- a/components/net/sf/briar/crypto/CryptoComponentImpl.java
+++ b/components/net/sf/briar/crypto/CryptoComponentImpl.java
@@ -1,6 +1,8 @@
 package net.sf.briar.crypto;
 
+import static javax.crypto.Cipher.ENCRYPT_MODE;
 import static net.sf.briar.api.plugins.InvitationConstants.CODE_BITS;
+import static net.sf.briar.api.transport.TransportConstants.TAG_LENGTH;
 import static net.sf.briar.util.ByteUtils.MAX_32_BIT_UNSIGNED;
 
 import java.security.GeneralSecurityException;
@@ -210,6 +212,23 @@ class CryptoComponentImpl implements CryptoComponent {
 		return counterModeKdf(secret, ROTATE, period);
 	}
 
+	public void encodeTag(byte[] tag, Cipher tagCipher, ErasableKey tagKey,
+			long connection) {
+		if(tag.length < TAG_LENGTH) throw new IllegalArgumentException();
+		if(connection < 0 || connection > MAX_32_BIT_UNSIGNED)
+			throw new IllegalArgumentException();
+		for(int i = 0; i < TAG_LENGTH; i++) tag[i] = 0;
+		ByteUtils.writeUint32(connection, tag, 0);
+		try {
+			tagCipher.init(ENCRYPT_MODE, tagKey);
+			int encrypted = tagCipher.doFinal(tag, 0, TAG_LENGTH, tag);
+			if(encrypted != TAG_LENGTH) throw new IllegalArgumentException();
+		} catch(GeneralSecurityException e) {
+			// Unsuitable cipher or key
+			throw new IllegalArgumentException(e);
+		}
+	}
+
 	public int generateInvitationCode() {
 		int codeBytes = (int) Math.ceil(CODE_BITS / 8.0);
 		byte[] random = new byte[codeBytes];
diff --git a/components/net/sf/briar/protocol/duplex/IncomingDuplexConnection.java b/components/net/sf/briar/protocol/duplex/IncomingDuplexConnection.java
index 0f51a449c3a8c3fd67d539360afaaa221f4fb78c..3ec37b99cf1a972faba991062ebe7c89149cc81a 100644
--- a/components/net/sf/briar/protocol/duplex/IncomingDuplexConnection.java
+++ b/components/net/sf/briar/protocol/duplex/IncomingDuplexConnection.java
@@ -34,12 +34,12 @@ class IncomingDuplexConnection extends DuplexConnection {
 	@Override
 	protected ConnectionReader createConnectionReader() throws IOException {
 		return connReaderFactory.createConnectionReader(
-				transport.getInputStream(), ctx, true);
+				transport.getInputStream(), ctx, true, true);
 	}
 
 	@Override
 	protected ConnectionWriter createConnectionWriter() throws IOException {
 		return connWriterFactory.createConnectionWriter(
-				transport.getOutputStream(), Long.MAX_VALUE, ctx, false);
+				transport.getOutputStream(), Long.MAX_VALUE, ctx, true, false);
 	}
 }
diff --git a/components/net/sf/briar/protocol/duplex/OutgoingDuplexConnection.java b/components/net/sf/briar/protocol/duplex/OutgoingDuplexConnection.java
index e3f9c8c723c0a97109e03501f2bc3786706f7330..8be0202ff6082243915cd6b218014e42b52cc3a5 100644
--- a/components/net/sf/briar/protocol/duplex/OutgoingDuplexConnection.java
+++ b/components/net/sf/briar/protocol/duplex/OutgoingDuplexConnection.java
@@ -34,12 +34,12 @@ class OutgoingDuplexConnection extends DuplexConnection {
 	@Override
 	protected ConnectionReader createConnectionReader() throws IOException {
 		return connReaderFactory.createConnectionReader(
-				transport.getInputStream(), ctx, false);
+				transport.getInputStream(), ctx, false, false);
 	}
 
 	@Override
 	protected ConnectionWriter createConnectionWriter() throws IOException {
 		return connWriterFactory.createConnectionWriter(
-				transport.getOutputStream(), Long.MAX_VALUE, ctx, true);
+				transport.getOutputStream(), Long.MAX_VALUE, ctx, false, true);
 	}
 }
diff --git a/components/net/sf/briar/protocol/simplex/IncomingSimplexConnection.java b/components/net/sf/briar/protocol/simplex/IncomingSimplexConnection.java
index 7a23a90e85e638cd3a06c4d4da14c144fb343124..d3a4266c7641708154e5185e9bf9454666cf1cee 100644
--- a/components/net/sf/briar/protocol/simplex/IncomingSimplexConnection.java
+++ b/components/net/sf/briar/protocol/simplex/IncomingSimplexConnection.java
@@ -65,7 +65,7 @@ class IncomingSimplexConnection {
 		connRegistry.registerConnection(contactId, transportId);
 		try {
 			ConnectionReader conn = connFactory.createConnectionReader(
-					transport.getInputStream(), ctx, true);
+					transport.getInputStream(), ctx, true, true);
 			InputStream in = conn.getInputStream();
 			ProtocolReader reader = protoFactory.createProtocolReader(in);
 			// Read packets until EOF
diff --git a/components/net/sf/briar/protocol/simplex/OutgoingSimplexConnection.java b/components/net/sf/briar/protocol/simplex/OutgoingSimplexConnection.java
index f6e2d40f20125f5c8c22e80f3491a537b152bc3a..9a30cd89ac2483e800622e05f888377e861c734c 100644
--- a/components/net/sf/briar/protocol/simplex/OutgoingSimplexConnection.java
+++ b/components/net/sf/briar/protocol/simplex/OutgoingSimplexConnection.java
@@ -59,7 +59,7 @@ class OutgoingSimplexConnection {
 		try {
 			ConnectionWriter conn = connFactory.createConnectionWriter(
 					transport.getOutputStream(), transport.getCapacity(),
-					ctx, true);
+					ctx, false, true);
 			OutputStream out = conn.getOutputStream();
 			ProtocolWriter writer = protoFactory.createProtocolWriter(out,
 					transport.shouldFlush());
diff --git a/components/net/sf/briar/transport/ConnectionReaderFactoryImpl.java b/components/net/sf/briar/transport/ConnectionReaderFactoryImpl.java
index c6fae40198acdf33190d326bdc1094bcb962c26a..dd31f3fe83da03795301ce2a1ca5d435cfa71508 100644
--- a/components/net/sf/briar/transport/ConnectionReaderFactoryImpl.java
+++ b/components/net/sf/briar/transport/ConnectionReaderFactoryImpl.java
@@ -22,12 +22,13 @@ class ConnectionReaderFactoryImpl implements ConnectionReaderFactory {
 	}
 
 	public ConnectionReader createConnectionReader(InputStream in,
-			ConnectionContext ctx, boolean initiator) {
+			ConnectionContext ctx, boolean incoming, boolean initiator) {
 		byte[] secret = ctx.getSecret();
 		long connection = ctx.getConnectionNumber();
-		boolean alice = ctx.getAlice();
-		ErasableKey frameKey = crypto.deriveFrameKey(secret, connection, alice,
-				initiator);
+		boolean weAreAlice = ctx.getAlice();
+		boolean initiatorIsAlice = incoming ? !weAreAlice : weAreAlice;
+		ErasableKey frameKey = crypto.deriveFrameKey(secret, connection,
+				initiatorIsAlice, initiator);
 		FrameReader encryption = new IncomingEncryptionLayer(in,
 				crypto.getFrameCipher(), frameKey, MAX_FRAME_LENGTH);
 		return new ConnectionReaderImpl(encryption, MAX_FRAME_LENGTH);
diff --git a/components/net/sf/briar/transport/ConnectionWriterFactoryImpl.java b/components/net/sf/briar/transport/ConnectionWriterFactoryImpl.java
index a56e4becd2e7dcf2714025f1fb4b978f0e5fbb3e..0b9404ea15499d72ce12bab909a9904bd2353d78 100644
--- a/components/net/sf/briar/transport/ConnectionWriterFactoryImpl.java
+++ b/components/net/sf/briar/transport/ConnectionWriterFactoryImpl.java
@@ -26,18 +26,20 @@ class ConnectionWriterFactoryImpl implements ConnectionWriterFactory {
 	}
 
 	public ConnectionWriter createConnectionWriter(OutputStream out,
-			long capacity, ConnectionContext ctx, boolean initiator) {
+			long capacity, ConnectionContext ctx, boolean incoming,
+			boolean initiator) {
 		byte[] secret = ctx.getSecret();
 		long connection = ctx.getConnectionNumber();
-		boolean alice = ctx.getAlice();
-		ErasableKey frameKey = crypto.deriveFrameKey(secret, connection, alice,
-				initiator);
+		boolean weAreAlice = ctx.getAlice();
+		boolean initiatorIsAlice = incoming ? !weAreAlice : weAreAlice;
+		ErasableKey frameKey = crypto.deriveFrameKey(secret, connection,
+				initiatorIsAlice, initiator);
 		FrameWriter encryption;
 		if(initiator) {
 			byte[] tag = new byte[TAG_LENGTH];
 			Cipher tagCipher = crypto.getTagCipher();
-			ErasableKey tagKey = crypto.deriveTagKey(secret, alice);
-			TagEncoder.encodeTag(tag, tagCipher, tagKey, connection);
+			ErasableKey tagKey = crypto.deriveTagKey(secret, initiatorIsAlice);
+			crypto.encodeTag(tag, tagCipher, tagKey, connection);
 			encryption = new OutgoingEncryptionLayer(out, capacity,
 					crypto.getFrameCipher(), frameKey, MAX_FRAME_LENGTH, tag);
 		} else {
diff --git a/components/net/sf/briar/transport/TagEncoder.java b/components/net/sf/briar/transport/TagEncoder.java
deleted file mode 100644
index fc0e1a85fc8ea28b30860be435937e250000de7d..0000000000000000000000000000000000000000
--- a/components/net/sf/briar/transport/TagEncoder.java
+++ /dev/null
@@ -1,32 +0,0 @@
-package net.sf.briar.transport;
-
-import static javax.crypto.Cipher.ENCRYPT_MODE;
-import static net.sf.briar.api.transport.TransportConstants.TAG_LENGTH;
-import static net.sf.briar.util.ByteUtils.MAX_32_BIT_UNSIGNED;
-
-import java.security.GeneralSecurityException;
-
-import javax.crypto.Cipher;
-
-import net.sf.briar.api.crypto.ErasableKey;
-import net.sf.briar.util.ByteUtils;
-
-class TagEncoder {
-
-	static void encodeTag(byte[] tag, Cipher tagCipher, ErasableKey tagKey,
-			long connection) {
-		if(tag.length < TAG_LENGTH) throw new IllegalArgumentException();
-		if(connection < 0 || connection > MAX_32_BIT_UNSIGNED)
-			throw new IllegalArgumentException();
-		for(int i = 0; i < TAG_LENGTH; i++) tag[i] = 0;
-		ByteUtils.writeUint32(connection, tag, 0);
-		try {
-			tagCipher.init(ENCRYPT_MODE, tagKey);
-			int encrypted = tagCipher.doFinal(tag, 0, TAG_LENGTH, tag);
-			if(encrypted != TAG_LENGTH) throw new IllegalArgumentException();
-		} catch(GeneralSecurityException e) {
-			// Unsuitable cipher or key
-			throw new IllegalArgumentException(e);
-		}
-	}
-}
diff --git a/components/net/sf/briar/transport/TransportConnectionRecogniser.java b/components/net/sf/briar/transport/TransportConnectionRecogniser.java
index c0525df306d1e2d235c532c3a0100cda019f078d..3ff70470ddd0b8c2c6db6fbedf9c3b94129860aa 100644
--- a/components/net/sf/briar/transport/TransportConnectionRecogniser.java
+++ b/components/net/sf/briar/transport/TransportConnectionRecogniser.java
@@ -51,10 +51,10 @@ class TransportConnectionRecogniser {
 		boolean alice = ctx.getAlice();
 		// Update the connection window and the expected tags
 		Cipher cipher = crypto.getTagCipher();
-		ErasableKey key = crypto.deriveTagKey(secret, alice);
+		ErasableKey key = crypto.deriveTagKey(secret, !alice);
 		for(long connection1 : window.setSeen(connection)) {
 			byte[] tag1 = new byte[TAG_LENGTH];
-			TagEncoder.encodeTag(tag1, cipher, key, connection1);
+			crypto.encodeTag(tag1, cipher, key, connection1);
 			if(connection1 <= connection) {
 				WindowContext old = tagMap.remove(new Bytes(tag1));
 				assert old != null;
@@ -84,11 +84,11 @@ class TransportConnectionRecogniser {
 		byte[] bitmap = s.getWindowBitmap();
 		// Create the connection window and the expected tags
 		Cipher cipher = crypto.getTagCipher();
-		ErasableKey key = crypto.deriveTagKey(secret, alice);
+		ErasableKey key = crypto.deriveTagKey(secret, !alice);
 		ConnectionWindow window = new ConnectionWindow(centre, bitmap);
 		for(long connection : window.getUnseen()) {
 			byte[] tag = new byte[TAG_LENGTH];
-			TagEncoder.encodeTag(tag, cipher, key, connection);
+			crypto.encodeTag(tag, cipher, key, connection);
 			ConnectionContext ctx = new ConnectionContext(contactId,
 					transportId, secret.clone(), connection, alice);
 			WindowContext wctx = new WindowContext(window, ctx, period);
@@ -113,10 +113,10 @@ class TransportConnectionRecogniser {
 	private void removeSecret(RemovalContext rctx) {
 		// Remove the expected tags
 		Cipher cipher = crypto.getTagCipher();
-		ErasableKey key = crypto.deriveTagKey(rctx.secret, rctx.alice);
+		ErasableKey key = crypto.deriveTagKey(rctx.secret, !rctx.alice);
 		byte[] tag = new byte[TAG_LENGTH];
 		for(long connection : rctx.window.getUnseen()) {
-			TagEncoder.encodeTag(tag, cipher, key, connection);
+			crypto.encodeTag(tag, cipher, key, connection);
 			WindowContext old = tagMap.remove(new Bytes(tag));
 			assert old != null;
 			ByteUtils.erase(old.context.getSecret());
diff --git a/test/net/sf/briar/ProtocolIntegrationTest.java b/test/net/sf/briar/ProtocolIntegrationTest.java
index f1bddbeaf74801bb9127dc0137658e971f9d8453..bbd7af2f9a7edb4387cac173311376d32b2fd1af 100644
--- a/test/net/sf/briar/ProtocolIntegrationTest.java
+++ b/test/net/sf/briar/ProtocolIntegrationTest.java
@@ -144,7 +144,7 @@ public class ProtocolIntegrationTest extends BriarTestCase {
 		ConnectionContext ctx = new ConnectionContext(contactId, transportId,
 				secret.clone(), 0L, true);
 		ConnectionWriter conn = connectionWriterFactory.createConnectionWriter(
-				out, Long.MAX_VALUE, ctx, true);
+				out, Long.MAX_VALUE, ctx, false, true);
 		OutputStream out1 = conn.getOutputStream();
 		ProtocolWriter writer = protocolWriterFactory.createProtocolWriter(out1,
 				false);
@@ -191,9 +191,9 @@ public class ProtocolIntegrationTest extends BriarTestCase {
 		assertEquals(TAG_LENGTH, in.read(tag, 0, TAG_LENGTH));
 		// FIXME: Check that the expected tag was received
 		ConnectionContext ctx = new ConnectionContext(contactId, transportId,
-				secret.clone(), 0L, true);
+				secret.clone(), 0L, false);
 		ConnectionReader conn = connectionReaderFactory.createConnectionReader(
-				in, ctx, true);
+				in, ctx, true, true);
 		InputStream in1 = conn.getInputStream();
 		ProtocolReader reader = protocolReaderFactory.createProtocolReader(in1);
 
diff --git a/test/net/sf/briar/protocol/simplex/SimplexProtocolIntegrationTest.java b/test/net/sf/briar/protocol/simplex/SimplexProtocolIntegrationTest.java
index f5495b205aecaff6334a042be19088157118387c..5caec2ff58dcda71df781c2020a25ecdfb4e5324 100644
--- a/test/net/sf/briar/protocol/simplex/SimplexProtocolIntegrationTest.java
+++ b/test/net/sf/briar/protocol/simplex/SimplexProtocolIntegrationTest.java
@@ -13,7 +13,9 @@ import net.sf.briar.BriarTestCase;
 import net.sf.briar.TestDatabaseModule;
 import net.sf.briar.TestUtils;
 import net.sf.briar.api.ContactId;
+import net.sf.briar.api.crypto.KeyManager;
 import net.sf.briar.api.db.DatabaseComponent;
+import net.sf.briar.api.db.TemporarySecret;
 import net.sf.briar.api.db.event.DatabaseEvent;
 import net.sf.briar.api.db.event.DatabaseListener;
 import net.sf.briar.api.db.event.MessagesAddedEvent;
@@ -48,11 +50,15 @@ import com.google.inject.Injector;
 
 public class SimplexProtocolIntegrationTest extends BriarTestCase {
 
+	private static final long CLOCK_DIFFERENCE = 60 * 1000L;
+	private static final long LATENCY = 60 * 1000L;
+
 	private final File testDir = TestUtils.getTestDirectory();
 	private final File aliceDir = new File(testDir, "alice");
 	private final File bobDir = new File(testDir, "bob");
 	private final TransportId transportId;
-	private final byte[] aliceToBobSecret, bobToAliceSecret;
+	private final byte[] secret;
+	private final long epoch;
 
 	private Injector alice, bob;
 
@@ -60,11 +66,10 @@ public class SimplexProtocolIntegrationTest extends BriarTestCase {
 		super();
 		transportId = new TransportId(TestUtils.getRandomId());
 		// Create matching secrets for Alice and Bob
-		Random r = new Random();
-		aliceToBobSecret = new byte[32];
-		r.nextBytes(aliceToBobSecret);
-		bobToAliceSecret = new byte[32];
-		r.nextBytes(bobToAliceSecret);
+		secret = new byte[32];
+		new Random().nextBytes(secret);
+		long rotationPeriod = 2 * CLOCK_DIFFERENCE + LATENCY;
+		epoch = System.currentTimeMillis() - 2 * rotationPeriod;
 	}
 
 	@Before
@@ -98,14 +103,22 @@ public class SimplexProtocolIntegrationTest extends BriarTestCase {
 		// Open Alice's database
 		DatabaseComponent db = alice.getInstance(DatabaseComponent.class);
 		db.open(false);
-		// Add Bob as a contact and send him a message
+		// Add Bob as a contact
 		ContactId contactId = db.addContact();
+		TemporarySecret s = new TemporarySecret(contactId, transportId, epoch,
+				CLOCK_DIFFERENCE, LATENCY, true, 0L, secret);
+		db.addContactTransport(s);
+		db.addSecrets(Collections.singletonList(s));
+		// Start Alice's key manager
+		KeyManager km = alice.getInstance(KeyManager.class);
+		km.start();
+		// Send Bob a message
 		String subject = "Hello";
 		byte[] body = "Hi Bob!".getBytes("UTF-8");
 		MessageFactory messageFactory = alice.getInstance(MessageFactory.class);
 		Message message = messageFactory.createMessage(null, subject, body);
 		db.addLocalPrivateMessage(message, contactId);
-		// Create an outgoing batch connection
+		// Create an outgoing simplex connection
 		ByteArrayOutputStream out = new ByteArrayOutputStream();
 		ConnectionRegistry connRegistry =
 				alice.getInstance(ConnectionRegistry.class);
@@ -115,17 +128,18 @@ public class SimplexProtocolIntegrationTest extends BriarTestCase {
 				alice.getInstance(ProtocolWriterFactory.class);
 		TestSimplexTransportWriter transport = new TestSimplexTransportWriter(
 				out, Long.MAX_VALUE, false);
-		ConnectionContext ctx = new ConnectionContext(contactId, transportId,
-				aliceToBobSecret, 0L, true);
+		ConnectionContext ctx = km.getConnectionContext(contactId, transportId);
+		assertNotNull(ctx);
 		OutgoingSimplexConnection simplex = new OutgoingSimplexConnection(db,
 				connRegistry, connFactory, protoFactory, ctx, transport);
 		// Write whatever needs to be written
 		simplex.write();
 		assertTrue(transport.getDisposed());
 		assertFalse(transport.getException());
-		// Close Alice's database
+		// Clean up
+		km.stop();
 		db.close();
-		// Return the contents of the batch connection
+		// Return the contents of the simplex connection
 		return out.toByteArray();
 	}
 
@@ -138,6 +152,13 @@ public class SimplexProtocolIntegrationTest extends BriarTestCase {
 		db.addListener(listener);
 		// Add Alice as a contact
 		ContactId contactId = db.addContact();
+		TemporarySecret s = new TemporarySecret(contactId, transportId, epoch,
+				CLOCK_DIFFERENCE, LATENCY, false, 0L, secret);
+		db.addContactTransport(s);
+		db.addSecrets(Collections.singletonList(s));
+		// Start Bob's key manager
+		KeyManager km = bob.getInstance(KeyManager.class);
+		km.start();
 		// Fake a transport update from Alice
 		TransportUpdate transportUpdate = new TransportUpdate() {
 
@@ -159,7 +180,6 @@ public class SimplexProtocolIntegrationTest extends BriarTestCase {
 		assertEquals(tag.length, read);
 		ConnectionContext ctx = rec.acceptConnection(transportId, tag);
 		assertNotNull(ctx);
-		assertEquals(contactId, ctx.getContactId());
 		// Create an incoming simplex connection
 		ConnectionRegistry connRegistry =
 				bob.getInstance(ConnectionRegistry.class);
@@ -181,7 +201,8 @@ public class SimplexProtocolIntegrationTest extends BriarTestCase {
 		assertTrue(transport.getRecognised());
 		// The private message from Alice should have been added
 		assertTrue(listener.messagesAdded);
-		// Close Bob's database
+		// Clean up
+		km.stop();
 		db.close();
 	}
 
diff --git a/test/net/sf/briar/transport/TransportIntegrationTest.java b/test/net/sf/briar/transport/TransportIntegrationTest.java
index 22ff5d7dcef9c0118f235f1be6c8746d66e3fa21..daa99b5b0233d657b1579c0f3b1b66614ed04468 100644
--- a/test/net/sf/briar/transport/TransportIntegrationTest.java
+++ b/test/net/sf/briar/transport/TransportIntegrationTest.java
@@ -136,7 +136,7 @@ public class TransportIntegrationTest extends BriarTestCase {
 		ConnectionContext ctx = new ConnectionContext(contactId, transportId,
 				secret, 0L, true);
 		ConnectionWriter w = connectionWriterFactory.createConnectionWriter(out,
-				MIN_CONNECTION_LENGTH, ctx, true);
+				MIN_CONNECTION_LENGTH, ctx, false, true);
 		// Check that the connection writer thinks there's room for a packet
 		long capacity = w.getRemainingCapacity();
 		assertTrue(capacity > MAX_PACKET_LENGTH);
@@ -157,7 +157,7 @@ public class TransportIntegrationTest extends BriarTestCase {
 		ConnectionContext ctx = new ConnectionContext(contactId, transportId,
 				secret, 0L, true);
 		ConnectionWriter w = connectionWriterFactory.createConnectionWriter(out,
-				MIN_CONNECTION_LENGTH, ctx, false);
+				MIN_CONNECTION_LENGTH, ctx, false, false);
 		// Check that the connection writer thinks there's room for a packet
 		long capacity = w.getRemainingCapacity();
 		assertTrue(capacity > MAX_PACKET_LENGTH);