diff --git a/apps/files_encryption/hooks/hooks.php b/apps/files_encryption/hooks/hooks.php
new file mode 100644
index 0000000000000000000000000000000000000000..89d526b70447e87926d62b7f6450fe21de673bfe
--- /dev/null
+++ b/apps/files_encryption/hooks/hooks.php
@@ -0,0 +1,50 @@
+<?php
+/**
+ * ownCloud
+ *
+ * @author Sam Tuke
+ * @copyright 2012 Sam Tuke samtuke@owncloud.org
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU AFFERO GENERAL PUBLIC LICENSE for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public
+ * License along with this library.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+namespace OCA_Encryption;
+
+/**
+ * Class for hook specific logic
+ */
+
+class Hooks {
+
+	public static function login( $params ){
+		
+		$view = new \OC_FilesystemView( '/' . $params['uid'] );
+		
+		$storage = new Storage( $view );
+		
+		if ( !$storage->ready() ) {
+		
+			return $storage->setup( $params['password'] );
+			
+		} else {
+		
+			return true;
+			
+		}
+	}
+
+}
+
+?>
\ No newline at end of file
diff --git a/apps/files_encryption/lib/crypt.php b/apps/files_encryption/lib/crypt.php
index 849e88ee0b2eb4fc521901121a17eabf5f7b0b92..7763f6bea56143ed904fa08bf24bcd5c4c9c1da2 100644
--- a/apps/files_encryption/lib/crypt.php
+++ b/apps/files_encryption/lib/crypt.php
@@ -2,8 +2,10 @@
 /**
  * ownCloud
  *
- * @author Frank Karlitschek
- * @copyright 2012 Frank Karlitschek frank@owncloud.org
+ * @author Sam Tuke, Frank Karlitschek, Robin Appelman
+ * @copyright 2012 Sam Tuke samtuke@owncloud.com, 
+ * Robin Appelman icewind@owncloud.com, Frank Karlitschek 
+ * frank@owncloud.org
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
@@ -20,135 +22,111 @@
  *
  */
 
-
-
-// Todo:
-//  - Crypt/decrypt button in the userinterface
-//  - Setting if crypto should be on by default
-//  - Add a setting "Don´t encrypt files larger than xx because of performance reasons"
-//  - Transparent decrypt/encrypt in filesystem.php. Autodetect if a file is encrypted (.encrypted extension)
-//  - Don't use a password directly as encryption key. but a key which is stored on the server and encrypted with the user password. -> password change faster
-//  - IMPORTANT! Check if the block lenght of the encrypted data stays the same
-
-
-require_once('Crypt_Blowfish/Blowfish.php');
+namespace OCA_Encryption;
 
 /**
- * This class is for crypting and decrypting
+ * Class for common cryptography functionality
  */
-class OC_Crypt {
-	static private $bf = null;
-
-	public static function loginListener($params){
-		self::init($params['uid'],$params['password']);
-	}
 
-	public static function init($login,$password) {
-		$view=new OC_FilesystemView('/');
-		if(!$view->file_exists('/'.$login)){
-			$view->mkdir('/'.$login);
-		}
+class Crypt {
 
-		OC_FileProxy::$enabled=false;
-		if(!$view->file_exists('/'.$login.'/encryption.key')){// does key exist?
-			OC_Crypt::createkey($login,$password);
-		}
-		$key=$view->file_get_contents('/'.$login.'/encryption.key');
-		OC_FileProxy::$enabled=true;
-		$_SESSION['enckey']=OC_Crypt::decrypt($key, $password);
-	}
+        /**
+         * @brief Create a new encryption keypair
+         * @return array publicKey, privatekey
+         */
+	public static function createKeypair() {
+	
+		$res = openssl_pkey_new();
 
+		// Get private key
+		openssl_pkey_export( $res, $privateKey );
 
-	/**
-	 * get the blowfish encryption handeler for a key
-	 * @param string $key (optional)
-	 * @return Crypt_Blowfish
-	 *
-	 * if the key is left out, the default handeler will be used
-	 */
-	public static function getBlowfish($key=''){
-		if($key){
-			return new Crypt_Blowfish($key);
-		}else{
-			if(!isset($_SESSION['enckey'])){
-				return false;
-			}
-			if(!self::$bf){
-				self::$bf=new Crypt_Blowfish($_SESSION['enckey']);
-			}
-			return self::$bf;
-		}
+		// Get public key
+		$publicKey = openssl_pkey_get_details( $res );
+		
+		$publicKey = $publicKey['key'];
+		
+		return( array( 'publicKey' => $publicKey, 'privateKey' => $privateKey ) );
+	
 	}
-
-	public static function createkey($username,$passcode) {
-		// generate a random key
-		$key=mt_rand(10000,99999).mt_rand(10000,99999).mt_rand(10000,99999).mt_rand(10000,99999);
-
-		// encrypt the key with the passcode of the user
-		$enckey=OC_Crypt::encrypt($key,$passcode);
-
-		// Write the file
-		$proxyEnabled=OC_FileProxy::$enabled;
-		OC_FileProxy::$enabled=false;
-		$view=new OC_FilesystemView('/'.$username);
-		$view->file_put_contents('/encryption.key',$enckey);
-		OC_FileProxy::$enabled=$proxyEnabled;
+	
+        /**
+         * @brief Symmetrically encrypt a file
+         * @returns encrypted file
+         */
+	public static function encrypt( $plainContent, $iv, $passphrase = '' ) {
+	
+		# TODO: Move these methods into a separate public class for app developers
+	
+		$iv64 = base64_encode( $iv );
+		
+		$raw = false; // true returns raw bytes, false returns base64
+		
+		if ( $encryptedContent = openssl_encrypt( $plainContent, 'AES-256-OFB', $passphrase, $raw, $iv ) ) {
+
+			return $encryptedContent;
+			
+		} else {
+		
+			\OC_Log::write( 'Encrypted storage', 'Encryption (symmetric) of file failed' , \OC_Log::ERROR );
+			
+			return false;
+			
+		}
+	
 	}
-
-	public static function changekeypasscode($oldPassword, $newPassword) {
-		if(OCP\User::isLoggedIn()){
-			$username=OCP\USER::getUser();
-			$view=new OC_FilesystemView('/'.$username);
-
-			// read old key
-			$key=$view->file_get_contents('/encryption.key');
-
-			// decrypt key with old passcode
-			$key=OC_Crypt::decrypt($key, $oldPassword);
-
-			// encrypt again with new passcode
-			$key=OC_Crypt::encrypt($key, $newPassword);
-
-			// store the new key
-			$view->file_put_contents('/encryption.key', $key );
+	
+        /**
+         * @brief Symmetrically decrypt a file
+         * @returns decrypted file
+         */
+	public static function decrypt( $encryptedContent, $iv, $passphrase ) {
+		
+// 		$iv64 = base64_encode( $iv );
+// 		
+// 		$iv = base64_decode( $iv64 );
+
+		$raw = false; // true returns raw bytes, false returns base64
+
+		if ( $plainContent = openssl_decrypt( $encryptedContent, 'AES-256-OFB', $passphrase, $raw, $iv) ) {
+
+			return $plainContent;
+		
+			
+		} else {
+		
+			\OC_Log::write( 'Encrypted storage', 'Decryption (symmetric) of file failed' , \OC_Log::ERROR );
+			
+			return false;
+			
 		}
+	
 	}
-
-	/**
-	 * @brief encrypts an content
-	 * @param $content the cleartext message you want to encrypt
-	 * @param $key the encryption key (optional)
-	 * @returns encrypted content
-	 *
-	 * This function encrypts an content
-	 */
-	public static function encrypt( $content, $key='') {
-		$bf = self::getBlowfish($key);
-		return $bf->encrypt($content);
+	
+        /**
+         * @brief Asymetrically encrypt a file using a public key
+         * @returns encrypted file
+         */
+	public static function keyEncrypt( $plainContent, $publicKey ) {
+	
+		openssl_public_encrypt( $plainContent, $encryptedContent, $publicKey );
+		
+		return $encryptedContent;
+	
 	}
-
-	/**
-	* @brief decryption of an content
-	* @param $content the cleartext message you want to decrypt
-	* @param $key the encryption key (optional)
-	* @returns cleartext content
-	*
-	* This function decrypts an content
-	*/
-	public static function decrypt( $content, $key='') {
-		$bf = self::getBlowfish($key);
-		$data=$bf->decrypt($content);
-		return $data;
+	
+        /**
+         * @brief Asymetrically decrypt a file using a private key
+         * @returns decrypted file
+         */
+	public static function keyDecrypt( $encryptedContent, $privatekey ) {
+
+		openssl_private_decrypt( $encryptedContent, $plainContent, $privatekey );
+		
+		return $plainContent;
+	
 	}
-
-	/**
-	* @brief encryption of a file
-	* @param string $source
-	* @param string $target
-	* @param string $key the decryption key
-	*
-	* This function encrypts a file
-	*/
+	
 	public static function encryptFile( $source, $target, $key='') {
 		$handleread  = fopen($source, "rb");
 		if($handleread!=FALSE) {
@@ -165,13 +143,13 @@ class OC_Crypt {
 
 
 	/**
-		* @brief decryption of a file
-		* @param string $source
-		* @param string $target
-		* @param string $key the decryption key
-		*
-		* This function decrypts a file
-		*/
+	* @brief decryption of a file
+	* @param string $source
+	* @param string $target
+	* @param string $key the decryption key
+	*
+	* This function decrypts a file
+	*/
 	public static function decryptFile( $source, $target, $key='') {
 		$handleread  = fopen($source, "rb");
 		if($handleread!=FALSE) {
@@ -189,31 +167,83 @@ class OC_Crypt {
 		}
 	}
 	
-	/**
-	 * encrypt data in 8192b sized blocks
-	 */
-	public static function blockEncrypt($data, $key=''){
-		$result='';
-		while(strlen($data)){
-			$result.=self::encrypt(substr($data,0,8192),$key);
-			$data=substr($data,8192);
+        /**
+         * @brief Encrypts data in 8192 byte sized blocks
+         * @returns encrypted data
+         */
+	public static function blockEncrypt( $data, $key = '' ){
+	
+		$result = '';
+		
+		while( strlen( $data ) ) {
+		
+			// Encrypt byte block
+			$result .= self::encrypt( substr( $data, 0, 8192 ), $key );
+			
+			$data = substr( $data, 8192 );
+		
 		}
+		
 		return $result;
 	}
 	
 	/**
 	 * decrypt data in 8192b sized blocks
 	 */
-	public static function blockDecrypt($data, $key='',$maxLength=0){
-		$result='';
-		while(strlen($data)){
-			$result.=self::decrypt(substr($data,0,8192),$key);
-			$data=substr($data,8192);
+	public static function blockDecrypt( $data, $key='', $maxLength = 0 ) {
+		
+		$result = '';
+		
+		while( strlen( $data ) ) {
+		
+			$result .= self::decrypt( substr( $data, 0, 8192 ), $key );
+			
+			$data = substr( $data,8192 );
+			
 		}
-		if($maxLength>0){
-			return substr($result,0,$maxLength);
-		}else{
-			return rtrim($result, "\0");
+		
+		if ( $maxLength > 0 ) {
+		
+			return substr( $result, 0, $maxLength );
+			
+		} else {
+		
+			return rtrim( $result, "\0" );
+			
 		}
 	}
+	
+        /**
+         * @brief Generate a random key for symmetric encryption
+         * @returns $key Generated key
+         */
+	public static function generateKey() {
+		
+		$key = mt_rand( 10000, 99999 ) . mt_rand( 10000, 99999 ) . mt_rand( 10000, 99999 ) . mt_rand( 10000, 99999 );
+		
+		return $key;
+		
+	}
+
+	public static function changekeypasscode($oldPassword, $newPassword) {
+		if(OCP\User::isLoggedIn()){
+			$username=OCP\USER::getUser();
+			$view=new OC_FilesystemView('/'.$username);
+
+			// read old key
+			$key=$view->file_get_contents('/encryption.key');
+
+			// decrypt key with old passcode
+			$key=OC_Crypt::decrypt($key, $oldPassword);
+
+			// encrypt again with new passcode
+			$key=OC_Crypt::encrypt($key, $newPassword);
+
+			// store the new key
+			$view->file_put_contents('/encryption.key', $key );
+		}
+	}
+
 }
+
+?>
\ No newline at end of file
diff --git a/apps/files_encryption/lib/proxy.php b/apps/files_encryption/lib/proxy.php
index f25e4a662f6ea568bcc6dc245dcef240780041f1..e06242e29d48c9d54ecb03bce66b4289030cbf92 100644
--- a/apps/files_encryption/lib/proxy.php
+++ b/apps/files_encryption/lib/proxy.php
@@ -21,6 +21,14 @@
 *
 */
 
+
+class OC_FileProxy_Encryption extends OC_FileProxy {
+
+	
+
+}
+
+
 /**
  * transparent encryption
  */
@@ -30,45 +38,76 @@ class OC_FileProxy_Encryption extends OC_FileProxy{
 	private static $enableEncryption=null;
 	
 	/**
-	 * check if a file should be encrypted during write
+	 * Check if a file requires encryption
 	 * @param string $path
 	 * @return bool
+	 *
+	 * Tests if encryption is enabled, and file is allowed by blacklists
 	 */
-	private static function shouldEncrypt($path){
-		if(is_null(self::$enableEncryption)){
-			self::$enableEncryption=(OCP\Config::getAppValue('files_encryption','enable_encryption','true')=='true');
+	private static function shouldEncrypt( $path ) {
+	
+		if ( is_null( self::$enableEncryption ) ) {
+		
+			self::$enableEncryption = ( OCP\Config::getAppValue( 'files_encryption', 'enable_encryption', 'true' ) == 'true' );
+			
 		}
-		if(!self::$enableEncryption){
+		
+		if( !self::$enableEncryption ) {
+		
 			return false;
+			
 		}
-		if(is_null(self::$blackList)){
-			self::$blackList=explode(',',OCP\Config::getAppValue('files_encryption','type_blacklist','jpg,png,jpeg,avi,mpg,mpeg,mkv,mp3,oga,ogv,ogg'));
+		
+		if( is_null(self::$blackList ) ) {
+		
+			self::$blackList = explode(',',OCP\Config::getAppValue( 'files_encryption','type_blacklist','jpg,png,jpeg,avi,mpg,mpeg,mkv,mp3,oga,ogv,ogg' ) );
+			
 		}
-		if(self::isEncrypted($path)){
+		
+		if( self::isEncrypted( $path ) ) {
+		
 			return true;
+			
 		}
-		$extension=substr($path,strrpos($path,'.')+1);
-		if(array_search($extension,self::$blackList)===false){
+		
+		$extension = substr( $path, strrpos( $path,'.' ) +1 );
+		
+		if ( array_search( $extension, self::$blackList ) === false ){
+		
 			return true;
+			
 		}
+		
+		return false;
 	}
 
 	/**
-	 * check if a file is encrypted
+	 * Check if a file is encrypted according to database file cache
 	 * @param string $path
 	 * @return bool
 	 */
-	private static function isEncrypted($path){
-		$metadata=OC_FileCache_Cached::get($path,'');
-		return isset($metadata['encrypted']) and (bool)$metadata['encrypted'];
+	private static function isEncrypted( $path ){
+	
+		// Fetch all file metadata from DB
+		$metadata = OC_FileCache_Cached::get( $path, '' );
+		
+		// Return encryption status
+		return isset( $metadata['encrypted'] ) and ( bool )$metadata['encrypted'];
+	
 	}
 	
-	public function preFile_put_contents($path,&$data){
-		if(self::shouldEncrypt($path)){
-			if (!is_resource($data)) {//stream put contents should have been converter to fopen
-				$size=strlen($data);
-				$data=OC_Crypt::blockEncrypt($data);
-				OC_FileCache::put($path,array('encrypted'=>true,'size'=>$size),'');
+	public function preFile_put_contents( $path, &$data ) {
+		
+		if ( self::shouldEncrypt( $path ) ) {
+		
+			if ( !is_resource( $data ) ) {//stream put contents should have been converter to fopen
+			
+				$size = strlen( $data );
+				
+				$data = Crypt::blockEncrypt( $data );
+				
+				OC_FileCache::put( $path, array( 'encrypted'=>true, 'size' => $size ), '' );
+				
 			}
 		}
 	}
diff --git a/apps/files_encryption/lib/util.php b/apps/files_encryption/lib/util.php
new file mode 100644
index 0000000000000000000000000000000000000000..d576b7529440fe32ca5838d11ef7d43ed87a8207
--- /dev/null
+++ b/apps/files_encryption/lib/util.php
@@ -0,0 +1,133 @@
+<?php
+/**
+ * ownCloud
+ *
+ * @author Sam Tuke, Frank Karlitschek
+ * @copyright 2012 Sam Tuke samtuke@owncloud.com, 
+ * Frank Karlitschek frank@owncloud.org
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU AFFERO GENERAL PUBLIC LICENSE for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public
+ * License along with this library.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+// Todo:
+//  - Crypt/decrypt button in the userinterface
+//  - Setting if crypto should be on by default
+//  - Add a setting "Don´t encrypt files larger than xx because of performance reasons"
+//  - Transparent decrypt/encrypt in filesystem.php. Autodetect if a file is encrypted (.encrypted extension)
+//  - Don't use a password directly as encryption key. but a key which is stored on the server and encrypted with the user password. -> password change faster
+//  - IMPORTANT! Check if the block lenght of the encrypted data stays the same
+
+namespace OCA_Encryption;
+
+/**
+ * Class for utilities relating to encrypted file storage system
+ */
+
+class Util {
+
+	private $view; // OC_FilesystemView object for filesystem operations
+	private $pwd; // User Password
+	private $client; // Client side encryption mode flag
+
+        /**
+         * @brief get a list of all available versions of a file in descending chronological order
+         * @param $filename file to find versions of, relative to the user files dir
+         * @param $count number of versions to return
+         * @returns array
+         */
+	public function __construct( \OC_FilesystemView $view, $client = false ) {
+	
+		$this->view = $view;
+		$this->client = $client;
+		
+	}
+	
+	public function ready() {
+		
+		if( 
+		!$this->view->file_exists( '/' . 'keyfiles' )
+		or !$this->view->file_exists( '/' . 'keypair' )
+		or !$this->view->file_exists( '/' . 'keypair' . '/'. 'encryption.public.key' )
+		or !$this->view->file_exists( '/' . 'keypair' . '/'. 'encryption.private.key' ) 
+		) {
+		
+			return false;
+			
+		} else {
+		
+			return true;
+			
+		}
+	
+	}
+	
+	public function setup( $passphrase = null ) {
+	
+		$publicKeyFileName = 'encryption.public.key';
+		$privateKeyFileName = 'encryption.private.key';
+	
+		// Log changes to user's filesystem
+		$this->appInfo = \OC_APP::getAppInfo( 'files_encryption' );
+		
+		\OC_Log::write( $this->appInfo['name'], 'File encryption for user will be set up' , \OC_Log::INFO );
+		
+		// Create mirrored keyfile directory
+		if( !$this->view->file_exists( '/' . 'keyfiles' ) ) {
+		
+			$this->view->mkdir( '/'. 'keyfiles' );
+		
+		}
+		
+		// Create keypair directory
+		if( !$this->view->file_exists( '/'. 'keypair' ) ) {
+		
+			$this->view->mkdir( '/'. 'keypair' );
+		
+		}
+		
+		// Create user keypair
+		if ( 
+		!$this->view->file_exists( '/'. 'keypair'. '/' . $publicKeyFileName ) 
+		or !$this->view->file_exists( '/'. 'keypair'. '/' . $privateKeyFileName ) 
+		) {
+		
+			// Generate keypair
+			$keypair = Crypt::createKeypair();
+			
+			// Save public key
+			$this->view->file_put_contents( '/'. 'keypair'. '/' . $publicKeyFileName, $keypair['publicKey'] );
+			
+			if ( $this->client == false ) {
+				
+				# TODO: Use proper IV in encryption
+				
+				// Encrypt private key with user pwd as passphrase
+				$encryptedPrivateKey = Crypt::encrypt( $keypair['privateKey'], 1234567890123456, $passphrase );
+				
+				// $iv = openssl_random_pseudo_bytes(16);
+				$this->view->file_put_contents( '/'. 'keypair'. '/' . $privateKeyFileName, $encryptedPrivateKey );
+				
+			} else {
+			
+				# TODO PHASE2: add public key to keyserver for client-side
+				# TODO PHASE2: encrypt private key using password / new client side specified key, instead of existing user pwd
+			
+			}
+			
+		}
+	
+	}
+
+}