diff --git a/README.md b/README.md
index bc82a70..1dd0907 100644
--- a/README.md
+++ b/README.md
@@ -1,73 +1,5 @@
 encfs-java
 ==========
 
-encfs-java is a Java library for accessing data in
-[EncFS](http://www.arg0.net/encfs) volumes. It is able to derive the volume key
-from a user password, decode encrypted filenames (IV chaining is implemented),
-decrypt file contents, create new volumes, move/copy/rename files and
-directories within the volume as well as encrypt file contents into the
-volume
-
-We do support all encfs volume configuration options, and are interoperable
-with the official encfs implementation (http://www.arg0.net/encfs). Currently
-we only support volume created with the latest version (1.7.4), but we target
-to be able to support volumes created with legacy versions as well.
-
-## Building
-
-encfs-java uses [Maven](http://maven.apache.org) for building. Assuming you
-have a working installation, simply run the following to build the code:
-
-    $ mvn compile
-
-To create a JAR file for using encfs-java from another application, do:
-
-    $ mvn package
-
-Which will create a JAR file in the {$PROJECT_ROOT}/target/ directory.
-
-## Usage
-
-This library comes with a demo/example application called EncFSShell. It is a
-simple shell supporting a few commands such as 'ls', 'cd', 'cat', 'mv' and 'cp'
-on an EncFS volume. After building the library, add the
-{$PROJECT_ROOT}/target/classes/ directory to your CLASSPATH, and run like so:
-
-    $ java -classpath ${PROJECT_ROOT}/target/classes EncFSShell /path/to/an/encfs/volume
-
-For using the library from another project, include the .JAR file in your
-classpath and import the org.mrpdaemon.encfs.sec package.s
-
-## API Documentation
-
-For API documentation, see:
-
-http://mrpdaemon.github.com/encfs-java/apidocs/index.html
-
-To test your own comment changes, generate up-to-date docs using Maven:
-
-    $ mvn javadoc:javadoc
-
-Which will place your documentation in ${PROJECT_ROOT}/target/site/apidocs/
-
-## Common issues
-
-If you are getting an exception due to "Illegal key size" and you are using Sun's JDK,
-you need to install the Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction
-Policy Files. See the following link for more information:
-
-Java 6 JCE Link http://www.oracle.com/technetwork/java/javase/downloads/jce-6-download-429243.html
-Java 7 JCE Link http://www.oracle.com/technetwork/java/javase/downloads/jce-7-download-432124.html
-Java 8 JCE Link http://www.oracle.com/technetwork/java/javase/downloads/jce8-download-2133166.html
-Extract files into JDK/JRE/lib/security folder (To whichever version of JRE/JDK x64/x86 you are using)
-
-Thanks to aormerod for pointing this out!
-
-## Licensing
-
-encfs-java is licensed under the Lesser GNU Public License, which allows non-GPL
-applications to make use of the library with the restriction that the source code
-for any modifications to the library itself need to be made available to be able
-to legally redistribute the modified library. For more information, please see the
-LICENSE file and the Free Software Foundation
-[website](http://www.gnu.org/licenses/lgpl.html).
+This branch contains a hack to cache decoded values better.
+This is to use with encfs-brute.
diff --git a/src/main/java/org/mrpdaemon/sec/encfs/EncFSBinaryConfig.java b/src/main/java/org/mrpdaemon/sec/encfs/EncFSBinaryConfig.java
new file mode 100644
index 0000000..3aed19d
--- /dev/null
+++ b/src/main/java/org/mrpdaemon/sec/encfs/EncFSBinaryConfig.java
@@ -0,0 +1,52 @@
+package org.mrpdaemon.sec.encfs;
+
+import java.io.IOException;
+import java.util.Arrays;
+
+public class EncFSBinaryConfig
+{
+	private EncFSConfig config;
+	private byte[] encodedVolumeKey;
+	private byte[] ivSeed;
+	private byte[] encryptedVolumeKey;
+	private byte[] saltData;
+
+	private EncFSBinaryConfig() { }
+
+	public static EncFSBinaryConfig from(EncFSConfig config)
+	throws IOException
+	{
+		EncFSBinaryConfig obj = new EncFSBinaryConfig();
+		obj.config = config;
+		obj.encodedVolumeKey = EncFSBase64.decode(config.getBase64EncodedVolumeKey());
+		obj.ivSeed = Arrays.copyOfRange(obj.encodedVolumeKey, 0, 4);
+		obj.encryptedVolumeKey = Arrays.copyOfRange(obj.encodedVolumeKey, 4, obj.encodedVolumeKey.length);
+		obj.saltData = EncFSBase64.decode(config.getBase64Salt());
+		return obj;
+	}
+
+	public EncFSConfig getConfig()
+	{
+		return config;
+	}
+
+	public byte[] getEncodedVolumeKey()
+	{
+		return encodedVolumeKey;
+	}
+
+	public byte[] getIvSeed()
+	{
+		return ivSeed;
+	}
+
+	public byte[] getEncryptedVolumeKey()
+	{
+		return encryptedVolumeKey;
+	}
+
+	public byte[] getSaltData()
+	{
+		return saltData;
+	}
+}
diff --git a/src/main/java/org/mrpdaemon/sec/encfs/EncFSPBKDF2Data.java b/src/main/java/org/mrpdaemon/sec/encfs/EncFSPBKDF2Data.java
new file mode 100644
index 0000000..56d4aae
--- /dev/null
+++ b/src/main/java/org/mrpdaemon/sec/encfs/EncFSPBKDF2Data.java
@@ -0,0 +1,77 @@
+package org.mrpdaemon.sec.encfs;
+
+import java.security.NoSuchAlgorithmException;
+import java.security.spec.InvalidKeySpecException;
+import java.security.spec.KeySpec;
+import java.util.Arrays;
+import javax.crypto.SecretKeyFactory;
+import javax.crypto.spec.PBEKeySpec;
+
+public class EncFSPBKDF2Data
+{
+	private static final SecretKeyFactory skf;
+
+	static {
+		try {
+			skf = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
+		} catch (NoSuchAlgorithmException ex) {
+			throw new RuntimeException(ex);
+		}
+	}
+
+	private String password;
+	private byte[] pbkdf2Data;
+	private byte[] passKeyData;
+	private byte[] passIvData;
+
+	private EncFSPBKDF2Data() { }
+
+	public static EncFSPBKDF2Data from(EncFSBinaryConfig config, String password)
+	throws InvalidKeySpecException
+	{
+		byte[] cipherSaltData = config.getSaltData();
+		int keySizeInBytes = config.getConfig().getVolumeKeySizeInBits() / 8;
+		KeySpec ks = new PBEKeySpec(password.toCharArray(), cipherSaltData,
+				config.getConfig().getIterationForPasswordKeyDerivationCount(),
+				(keySizeInBytes + EncFSVolume.IV_LENGTH_IN_BYTES) * 8
+		);
+		byte[] pbkdf2Data = skf.generateSecret(ks).getEncoded();
+
+		EncFSPBKDF2Data obj;
+		obj = EncFSPBKDF2Data.from(config, pbkdf2Data);
+		obj.password = password;
+		return obj;
+	}
+
+	public static EncFSPBKDF2Data from(EncFSBinaryConfig config, byte[] pbkdf2Data)
+	throws InvalidKeySpecException
+	{
+		EncFSPBKDF2Data obj = new EncFSPBKDF2Data();
+		int keySizeInBytes = config.getConfig().getVolumeKeySizeInBits() / 8;
+		obj.pbkdf2Data = pbkdf2Data;
+		obj.passKeyData = Arrays.copyOfRange(pbkdf2Data, 0, keySizeInBytes);
+		obj.passIvData = Arrays.copyOfRange(pbkdf2Data, keySizeInBytes,
+				keySizeInBytes + EncFSVolume.IV_LENGTH_IN_BYTES);
+
+		return obj;
+	}
+
+	public String getPassword()
+	{
+		return password;
+	}
+	public byte[] getPbkdf2Data()
+	{
+		return pbkdf2Data;
+	}
+
+	public byte[] getPassKeyData()
+	{
+		return passKeyData;
+	}
+
+	public byte[] getPassIvData()
+	{
+		return passIvData;
+	}
+}
diff --git a/src/main/java/org/mrpdaemon/sec/encfs/EncFSUtil.java b/src/main/java/org/mrpdaemon/sec/encfs/EncFSUtil.java
index 314a6d2..290b873 100644
--- a/src/main/java/org/mrpdaemon/sec/encfs/EncFSUtil.java
+++ b/src/main/java/org/mrpdaemon/sec/encfs/EncFSUtil.java
@@ -129,6 +129,12 @@ public final class EncFSUtil {
 		}
 	}
 
+	public static boolean checkPassword(EncFSBinaryConfig config,
+			String password) throws EncFSUnsupportedException,
+			EncFSInvalidConfigException, EncFSCorruptDataException {
+		return VolumeKey.checkVolumeKey(config, password);
+	}
+
 	private static void readFromAndWriteTo(InputStream in, OutputStream out)
 			throws IOException {
 		byte[] buf = new byte[EIGHT_KILO];
diff --git a/src/main/java/org/mrpdaemon/sec/encfs/VolumeKey.java b/src/main/java/org/mrpdaemon/sec/encfs/VolumeKey.java
index 4f65ae0..6f24bda 100644
--- a/src/main/java/org/mrpdaemon/sec/encfs/VolumeKey.java
+++ b/src/main/java/org/mrpdaemon/sec/encfs/VolumeKey.java
@@ -15,11 +15,9 @@
 package org.mrpdaemon.sec.encfs;
 
 import javax.crypto.*;
-import javax.crypto.spec.PBEKeySpec;
 import java.io.IOException;
 import java.security.*;
 import java.security.spec.InvalidKeySpecException;
-import java.security.spec.KeySpec;
 import java.util.Arrays;
 
 // Class containing static methods implementing volume key functionality
@@ -74,39 +72,73 @@ class VolumeKey {
 			EncFSUnsupportedException {
 		// Decode Base64 encoded ciphertext data
 		// TODO: validate key/IV lengths
-		byte[] cipherVolKeyData;
+		EncFSBinaryConfig binaryConfig;
+		EncFSPBKDF2Data pbkdf2DataObj;
 		try {
-			cipherVolKeyData = EncFSBase64.decode(config
-					.getBase64EncodedVolumeKey());
-		} catch (IOException e) {
-			throw new EncFSInvalidConfigException("Corrupt key data in config");
+			binaryConfig = EncFSBinaryConfig.from(config);
+			pbkdf2DataObj = EncFSPBKDF2Data.from(binaryConfig, pbkdf2Data);
+		} catch (Exception e) {
+			throw new EncFSInvalidConfigException(e);
 		}
 
-		byte[] encryptedVolKey = Arrays.copyOfRange(cipherVolKeyData, 4,
-				cipherVolKeyData.length);
+		DecryptInfo info = decryptAnyVolumeKey(binaryConfig, pbkdf2DataObj);
+
+		boolean checksumOk = checkVolumeKey(binaryConfig, info);
+
+		if (!checksumOk) {
+			throw new EncFSChecksumException("Volume key checksum mismatch");
+		}
+
+		return info.clearVolKeyData;
+	}
+
+	protected static DecryptInfo decryptAnyVolumeKey(EncFSBinaryConfig config,
+			EncFSPBKDF2Data pbkdf2Data)
+			throws EncFSInvalidConfigException, EncFSCorruptDataException,
+			EncFSUnsupportedException {
+		byte[] encryptedVolKey = config.getEncryptedVolumeKey();
 
 		// Prepare key/IV for decryption
-		int keySizeInBytes = config.getVolumeKeySizeInBits() / 8;
-		byte[] passKeyData = Arrays.copyOfRange(pbkdf2Data, 0, keySizeInBytes);
-		byte[] passIvData = Arrays.copyOfRange(pbkdf2Data, keySizeInBytes,
-				keySizeInBytes + EncFSVolume.IV_LENGTH_IN_BYTES);
+		byte[] passKeyData = pbkdf2Data.getPassKeyData();
+		byte[] passIvData = pbkdf2Data.getPassIvData();
 
 		Key passKey = EncFSCrypto.newKey(passKeyData);
-		byte[] ivSeed = Arrays.copyOfRange(cipherVolKeyData, 0, 4);
+		byte[] ivSeed = config.getIvSeed();
 
 		// Decrypt the volume key data
 		Mac mac = encryptVolumeKeyData(passKey);
 		byte[] clearVolKeyData = decryptVolumeKeyData(encryptedVolKey,
 				passIvData, passKey, ivSeed, mac);
 
-		// Perform checksum computation
-		byte[] mac32 = EncFSCrypto.mac32(mac, clearVolKeyData, new byte[0]);
+		DecryptInfo info = new DecryptInfo();
+		info.clearVolKeyData = clearVolKeyData;
+		info.mac = mac;
+		return info;
+	}
 
-		if (!Arrays.equals(ivSeed, mac32)) {
-			throw new EncFSChecksumException("Volume key checksum mismatch");
+	public static boolean checkVolumeKey(EncFSBinaryConfig binaryConfig,
+			String password) throws EncFSUnsupportedException,
+			EncFSInvalidConfigException, EncFSCorruptDataException {
+		EncFSPBKDF2Data pbkdf2DataObj;
+		try {
+			pbkdf2DataObj = EncFSPBKDF2Data.from(binaryConfig, password);
+		} catch (InvalidKeySpecException ex) {
+			throw new EncFSUnsupportedException(ex);
 		}
 
-		return clearVolKeyData;
+		DecryptInfo info = decryptAnyVolumeKey(binaryConfig, pbkdf2DataObj);
+
+		boolean checksumOk = checkVolumeKey(binaryConfig, info);
+		return checksumOk;
+	}
+
+	private static boolean checkVolumeKey(EncFSBinaryConfig config,
+			DecryptInfo info) throws EncFSInvalidConfigException,
+			EncFSCorruptDataException, EncFSUnsupportedException {
+		byte[] mac32 = EncFSCrypto.mac32(info.mac, info.clearVolKeyData, new byte[0]);
+		byte[] ivSeed = config.getIvSeed();
+
+		return Arrays.equals(ivSeed, mac32);
 	}
 
 	// Decrypt volume key data
@@ -142,25 +174,11 @@ class VolumeKey {
 		}
 
 		if (pbkdf2Provider == null) {
-			// Execute PBKDF2 to derive key data from the password
-			SecretKeyFactory f;
 			try {
-				f = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
-			} catch (NoSuchAlgorithmException e) {
-				throw new EncFSUnsupportedException(e);
-			}
-			KeySpec ks = new PBEKeySpec(password.toCharArray(), cipherSaltData,
-					config.getIterationForPasswordKeyDerivationCount(),
-					config.getVolumeKeySizeInBits()
-							+ EncFSVolume.IV_LENGTH_IN_BYTES * 8);
-			SecretKey pbkdf2Key;
-			try {
-				pbkdf2Key = f.generateSecret(ks);
-			} catch (InvalidKeySpecException e) {
+				return EncFSPBKDF2Data.from(EncFSBinaryConfig.from(config), password).getPbkdf2Data();
+			} catch (Exception e) {
 				throw new EncFSInvalidConfigException(e);
 			}
-
-			return pbkdf2Key.getEncoded();
 		} else {
 			return pbkdf2Provider.doPBKDF2(password, cipherSaltData.length,
 					cipherSaltData,
@@ -193,4 +211,9 @@ class VolumeKey {
 		config.setEncodedKeyLengthInBytes(encodedVolKey.length);
 		config.setBase64EncodedVolumeKey(EncFSBase64.encodeBytes(encodedVolKey));
 	}
+
+	private static class DecryptInfo {
+		byte[] clearVolKeyData;
+		Mac mac;
+	}
 }