diff --git a/apps/files_encryption/lib/keymanager.php b/apps/files_encryption/lib/keymanager.php
index dfde3684798d50c86beb51448a4b484602da022b..925bba578f45e7653380905725f2ea97d08a512e 100644
--- a/apps/files_encryption/lib/keymanager.php
+++ b/apps/files_encryption/lib/keymanager.php
@@ -35,6 +35,8 @@ class Keymanager {
 	private static $encryption_base_dir = '/files_encryption';
 	private static $public_key_dir = '/files_encryption/public_keys';
 
+	private static $key_cache = array(); // cache keys
+
 	/**
 	 * read key from hard disk
 	 *
@@ -42,15 +44,24 @@ class Keymanager {
 	 * @return string|bool either the key or false
 	 */
 	private static function getKey($path, $view) {
-		$proxyStatus = \OC_FileProxy::$enabled;
-		\OC_FileProxy::$enabled = false;
 
 		$key = false;
-		if ($view->file_exists($path)) {
-			$key = $view->file_get_contents($path);
-		}
 
-		\OC_FileProxy::$enabled = $proxyStatus;
+		if (isset(self::$key_cache[$path])) {
+			$key =  self::$key_cache[$path];
+		} else {
+
+			$proxyStatus = \OC_FileProxy::$enabled;
+			\OC_FileProxy::$enabled = false;
+
+			if ($view->file_exists($path)) {
+				$key = $view->file_get_contents($path);
+				self::$key_cache[$path] = $key;
+			}
+
+			\OC_FileProxy::$enabled = $proxyStatus;
+
+		}
 
 		return $key;
 	}
@@ -70,11 +81,17 @@ class Keymanager {
 		\OC_FileProxy::$enabled = false;
 
 		self::keySetPreparation($view, $path);
-		$result = $view->file_put_contents($path . '/' . $name, $key);
+		$pathToKey = \OC\Files\Filesystem::normalizePath($path . '/' . $name);
+		$result = $view->file_put_contents($pathToKey, $key);
 
 		\OC_FileProxy::$enabled = $proxyStatus;
 
-		return (is_int($result) && $result > 0) ? true : false;
+		if (is_int($result) && $result > 0) {
+			self::$key_cache[$pathToKey] = $key;
+			return true;
+		}
+
+		return false;
 	}
 
 	/**
@@ -209,6 +226,25 @@ class Keymanager {
 		return $keyDir . $uid . '.shareKey';
 	}
 
+	/**
+	 * delete key
+	 *
+	 * @param \OC\Files\View $view
+	 * @param string $path
+	 * @return boolean
+	 */
+	private static function deleteKey($view, $path) {
+		$normalizedPath = \OC\Files\Filesystem::normalizePath($path);
+		$result = $view->unlink($normalizedPath);
+
+		if ($result) {
+			unset(self::$key_cache[$normalizedPath]);
+			return true;
+		}
+
+		return false;
+	}
+
 	/**
 	 * delete public key from a given user
 	 *
@@ -222,7 +258,7 @@ class Keymanager {
 
 		if (!\OCP\User::userExists($uid)) {
 			$publicKey = self::$public_key_dir . '/' . $uid . '.publicKey';
-			$result = $view->unlink($publicKey);
+			self::deleteKey($view, $publicKey);
 		}
 
 		return $result;
@@ -426,7 +462,7 @@ class Keymanager {
 						foreach ($userIds as $userId) {
 							if ($userId . '.shareKey' === $file) {
 								\OCP\Util::writeLog('files_encryption', 'recursiveDelShareKey: delete share key: ' . $file, \OCP\Util::DEBUG);
-								$view->unlink($dir . '/' . $file);
+								self::deleteKey($view, $dir . '/' . $file);
 							}
 						}
 					}
diff --git a/apps/files_encryption/tests/keymanager.php b/apps/files_encryption/tests/keymanager.php
index 82df9350d4b800be15249a937e52bf16b2be97fb..0d17923664db74e2ded22d272d3aa5bdad90d0c1 100644
--- a/apps/files_encryption/tests/keymanager.php
+++ b/apps/files_encryption/tests/keymanager.php
@@ -84,6 +84,24 @@ class Keymanager extends TestCase {
 		parent::tearDownAfterClass();
 	}
 
+	function testKeyCacheUpdate() {
+		$testUser = 'testKeyCacheUpdate';
+		\OCA\Files_Encryption\Keymanager::setPublicKey('oldKey', $testUser);
+
+		$this->assertSame('oldKey',
+				\OCA\Files_Encryption\Keymanager::getPublicKey($this->view, $testUser));
+
+		// update key
+		\OCA\Files_Encryption\Keymanager::setPublicKey('newKey', $testUser);
+
+		$this->assertSame('newKey',
+				\OCA\Files_Encryption\Keymanager::getPublicKey($this->view, $testUser));
+
+		// cleanup
+		\OCA\Files_Encryption\Keymanager::deletePublicKey($this->view, $testUser);
+
+	}
+
 	/**
 	 * @medium
 	 */
@@ -306,13 +324,14 @@ class Keymanager extends TestCase {
 		$this->view->file_put_contents('/' . self::TEST_USER . '/files/folder1/existingFile.txt', 'data');
 
 		// create folder structure for some dummy share key files
-		$this->view->mkdir('/' . self::TEST_USER . '/files_encryption/share-keys/folder1');
+		$this->view->mkdir('/' . self::TEST_USER . '/files_encryption/keys/folder1');
+		$this->view->mkdir('/' . self::TEST_USER . '/files_encryption/keys/folder1/existingFile.txt');
 
 		// create some dummy share keys
-		$this->view->file_put_contents('/' . self::TEST_USER . '/files_encryption/share-keys/folder1/existingFile.txt.user1.shareKey', 'data');
-		$this->view->file_put_contents('/' . self::TEST_USER . '/files_encryption/share-keys/folder1/existingFile.txt.user2.shareKey', 'data');
-		$this->view->file_put_contents('/' . self::TEST_USER . '/files_encryption/share-keys/folder1/existingFile.txt.user3.shareKey', 'data');
-		$this->view->file_put_contents('/' . self::TEST_USER . '/files_encryption/share-keys/folder1/existingFile.txt.' . self::TEST_USER . '.shareKey', 'data');
+		$this->view->file_put_contents('/' . self::TEST_USER . '/files_encryption/keys/folder1/existingFile.txt/user1.shareKey', 'data');
+		$this->view->file_put_contents('/' . self::TEST_USER . '/files_encryption/keys/folder1/existingFile.txt/user2.shareKey', 'data');
+		$this->view->file_put_contents('/' . self::TEST_USER . '/files_encryption/keys/folder1/existingFile.txt/user3.shareKey', 'data');
+		$this->view->file_put_contents('/' . self::TEST_USER . '/files_encryption/keys/folder1/existingFile.txt/' . self::TEST_USER . '.shareKey', 'data');
 
 		// recursive delete share keys from user1 and user2
 		\OCA\Files_Encryption\Keymanager::delShareKey($this->view,
@@ -324,15 +343,15 @@ class Keymanager extends TestCase {
 
 		// check if share keys from user1 and user2 are deleted
 		$this->assertFalse($this->view->file_exists(
-			'/' . self::TEST_USER . '/files_encryption/share-keys/folder1/existingFile.user1.shareKey'));
+			'/' . self::TEST_USER . '/files_encryption/keys/folder1/existingFile/user1.shareKey'));
 		$this->assertFalse($this->view->file_exists(
-				'/' . self::TEST_USER . '/files_encryption/share-keys/folder1/existingFile.user2.shareKey'));
+				'/' . self::TEST_USER . '/files_encryption/keys/folder1/existingFile/user2.shareKey'));
 
 		// check if share keys for user3 and owner
 		$this->assertTrue($this->view->file_exists(
-				'/' . self::TEST_USER . '/files_encryption/share-keys/folder1/existingFile.txt.' . self::TEST_USER . '.shareKey'));
+				'/' . self::TEST_USER . '/files_encryption/keys/folder1/existingFile.txt/' . self::TEST_USER . '.shareKey'));
 		$this->assertTrue($this->view->file_exists(
-				'/' . self::TEST_USER . '/files_encryption/share-keys/folder1/existingFile.txt.user3.shareKey'));
+				'/' . self::TEST_USER . '/files_encryption/keys/folder1/existingFile.txt/user3.shareKey'));
 		// cleanup
 		$this->view->deleteAll('/' . self::TEST_USER . '/files/folder1');
 
diff --git a/apps/files_encryption/tests/testcase.php b/apps/files_encryption/tests/testcase.php
index 9cb724648cb4fcebf428049f1af79f8441a6a8e9..c2e5f4de8c185a8a357249a09fd5134e2fa99b24 100644
--- a/apps/files_encryption/tests/testcase.php
+++ b/apps/files_encryption/tests/testcase.php
@@ -79,4 +79,18 @@ abstract class TestCase extends \Test\TestCase {
 
 		parent::tearDownAfterClass();
 	}
+
+	protected function tearDown() {
+		parent::tearDown();
+		$this->resetKeyCache();
+	}
+
+	protected function resetKeyCache() {
+		// reset key cache for every testrun
+		$keyCache = new \ReflectionProperty('\OCA\Files_Encryption\Keymanager', 'key_cache');
+		$keyCache->setAccessible(true);
+		$keyCache->setValue(array());
+		$keyCache->setAccessible(false);
+	}
+
 }
diff --git a/apps/files_encryption/tests/util.php b/apps/files_encryption/tests/util.php
index c71b9a0481fe9a635dcd04e0e0ed134aca32892d..c75f406cb61e2aa3a42d038e74185e8444d899f1 100755
--- a/apps/files_encryption/tests/util.php
+++ b/apps/files_encryption/tests/util.php
@@ -445,6 +445,9 @@ class Util extends TestCase {
 		$this->view->rename($this->userId . '/files_encryption/keys/' . $file1 . '/fileKey',
 				$this->userId . '/files_encryption/keys/' . $file1 . '/fileKey.moved');
 
+		// need to reset key cache that we don't use the cached key
+		$this->resetKeyCache();
+
 		// decrypt all encrypted files
 		$result = $util->decryptAll();