diff --git a/bramble-core/src/main/java/org/briarproject/bramble/crypto/CryptoComponentImpl.java b/bramble-core/src/main/java/org/briarproject/bramble/crypto/CryptoComponentImpl.java
index 25969d0eb36dc9a68a26bcf85de9db7bdc9214db..44e7f353c72a80a5ae4cb123573753e81d17f5b2 100644
--- a/bramble-core/src/main/java/org/briarproject/bramble/crypto/CryptoComponentImpl.java
+++ b/bramble-core/src/main/java/org/briarproject/bramble/crypto/CryptoComponentImpl.java
@@ -31,6 +31,7 @@ import java.security.SecureRandom;
 import java.security.Security;
 import java.util.logging.Logger;
 
+import javax.annotation.Nullable;
 import javax.inject.Inject;
 
 import static java.util.logging.Level.INFO;
@@ -48,6 +49,7 @@ class CryptoComponentImpl implements CryptoComponent {
 	private static final int ED_KEY_PAIR_BITS = 256;
 	private static final int STORAGE_IV_BYTES = 24; // 196 bits
 	private static final int PBKDF_SALT_BYTES = 32; // 256 bits
+	private static final int PBKDF_FORMAT_SCRYPT = 0;
 
 	private final SecureRandom secureRandom;
 	private final PasswordBasedKdf passwordBasedKdf;
@@ -341,17 +343,27 @@ class CryptoComponentImpl implements CryptoComponent {
 		// Generate a random IV
 		byte[] iv = new byte[STORAGE_IV_BYTES];
 		secureRandom.nextBytes(iv);
-		// The output contains the salt, cost parameter, IV, ciphertext and MAC
-		int outputLen = salt.length + INT_32_BYTES + iv.length + input.length
-				+ macBytes;
+		// The output contains the format version, salt, cost parameter, IV,
+		// ciphertext and MAC
+		int outputLen = 1 + salt.length + INT_32_BYTES + iv.length
+				+ input.length + macBytes;
 		byte[] output = new byte[outputLen];
-		System.arraycopy(salt, 0, output, 0, salt.length);
-		ByteUtils.writeUint32(cost, output, salt.length);
-		System.arraycopy(iv, 0, output, salt.length + INT_32_BYTES, iv.length);
+		int outputOff = 0;
+		// Format version
+		output[outputOff] = PBKDF_FORMAT_SCRYPT;
+		outputOff++;
+		// Salt
+		System.arraycopy(salt, 0, output, outputOff, salt.length);
+		outputOff += salt.length;
+		// Cost parameter
+		ByteUtils.writeUint32(cost, output, outputOff);
+		outputOff += INT_32_BYTES;
+		// IV
+		System.arraycopy(iv, 0, output, outputOff, iv.length);
+		outputOff += iv.length;
 		// Initialise the cipher and encrypt the plaintext
 		try {
 			cipher.init(true, key, iv);
-			int outputOff = salt.length + INT_32_BYTES + iv.length;
 			cipher.process(input, 0, input.length, output, outputOff);
 			return output;
 		} catch (GeneralSecurityException e) {
@@ -360,20 +372,34 @@ class CryptoComponentImpl implements CryptoComponent {
 	}
 
 	@Override
+	@Nullable
 	public byte[] decryptWithPassword(byte[] input, String password) {
 		AuthenticatedCipher cipher = new XSalsa20Poly1305AuthenticatedCipher();
 		int macBytes = cipher.getMacBytes();
-		// The input contains the salt, cost parameter, IV, ciphertext and MAC
-		if (input.length < PBKDF_SALT_BYTES + INT_32_BYTES + STORAGE_IV_BYTES
-				+ macBytes)
+		// The input contains the format version, salt, cost parameter, IV,
+		// ciphertext and MAC
+		if (input.length < 1 + PBKDF_SALT_BYTES + INT_32_BYTES
+				+ STORAGE_IV_BYTES + macBytes)
 			return null; // Invalid input
+		int inputOff = 0;
+		// Format version
+		byte formatVersion = input[inputOff];
+		inputOff++;
+		if (formatVersion != PBKDF_FORMAT_SCRYPT)
+			return null; // Unknown format
+		// Salt
 		byte[] salt = new byte[PBKDF_SALT_BYTES];
-		System.arraycopy(input, 0, salt, 0, salt.length);
-		long cost = ByteUtils.readUint32(input, salt.length);
+		System.arraycopy(input, inputOff, salt, 0, salt.length);
+		inputOff += salt.length;
+		// Cost parameter
+		long cost = ByteUtils.readUint32(input, inputOff);
+		inputOff += INT_32_BYTES;
 		if (cost < 2 || cost > Integer.MAX_VALUE)
 			return null; // Invalid cost parameter
+		// IV
 		byte[] iv = new byte[STORAGE_IV_BYTES];
-		System.arraycopy(input, salt.length + INT_32_BYTES, iv, 0, iv.length);
+		System.arraycopy(input, inputOff, iv, 0, iv.length);
+		inputOff += iv.length;
 		// Derive the key from the password
 		SecretKey key = passwordBasedKdf.deriveKey(password, salt, (int) cost);
 		// Initialise the cipher
@@ -384,7 +410,6 @@ class CryptoComponentImpl implements CryptoComponent {
 		}
 		// Try to decrypt the ciphertext (may be invalid)
 		try {
-			int inputOff = salt.length + INT_32_BYTES + iv.length;
 			int inputLen = input.length - inputOff;
 			byte[] output = new byte[inputLen - macBytes];
 			cipher.process(input, inputOff, inputLen, output, 0);