diff --git a/core/Application.php b/core/Application.php
index 6c6a3768a0f57488b5b6afd73d1e9104c81ebf14..f68f7929e6a716ff87622061316c84b5560843f7 100644
--- a/core/Application.php
+++ b/core/Application.php
@@ -44,6 +44,7 @@ class Application extends App {
 		parent::__construct('core');
 
 		$container = $this->getContainer();
+
 		$container->registerService('defaultMailAddress', function() {
 			return Util::getDefaultEmailAddress('lostpassword-noreply');
 		});
diff --git a/core/Controller/LostController.php b/core/Controller/LostController.php
index bfc24bd1e0fced11cfccb8b48ee17480124e0640..01c107e832632dd689345edb0cd87ce16b9919f4 100644
--- a/core/Controller/LostController.php
+++ b/core/Controller/LostController.php
@@ -40,6 +40,7 @@ use \OCP\IL10N;
 use \OCP\IConfig;
 use OCP\IUserManager;
 use OCP\Mail\IMailer;
+use OCP\Security\ICrypto;
 use OCP\Security\ISecureRandom;
 
 /**
@@ -71,6 +72,8 @@ class LostController extends Controller {
 	protected $mailer;
 	/** @var ITimeFactory */
 	protected $timeFactory;
+	/** @var ICrypto */
+	protected $crypto;
 
 	/**
 	 * @param string $appName
@@ -85,6 +88,7 @@ class LostController extends Controller {
 	 * @param IManager $encryptionManager
 	 * @param IMailer $mailer
 	 * @param ITimeFactory $timeFactory
+	 * @param ICrypto $crypto
 	 */
 	public function __construct($appName,
 								IRequest $request,
@@ -97,7 +101,8 @@ class LostController extends Controller {
 								$defaultMailAddress,
 								IManager $encryptionManager,
 								IMailer $mailer,
-								ITimeFactory $timeFactory) {
+								ITimeFactory $timeFactory,
+								ICrypto $crypto) {
 		parent::__construct($appName, $request);
 		$this->urlGenerator = $urlGenerator;
 		$this->userManager = $userManager;
@@ -109,6 +114,7 @@ class LostController extends Controller {
 		$this->config = $config;
 		$this->mailer = $mailer;
 		$this->timeFactory = $timeFactory;
+		$this->crypto = $crypto;
 	}
 
 	/**
@@ -150,8 +156,19 @@ class LostController extends Controller {
 	 */
 	private function checkPasswordResetToken($token, $userId) {
 		$user = $this->userManager->get($userId);
+		if($user === null) {
+			throw new \Exception($this->l10n->t('Couldn\'t reset password because the token is invalid'));
+		}
+
+		try {
+			$encryptedToken = $this->config->getUserValue($userId, 'core', 'lostpassword', null);
+			$mailAddress = !is_null($user->getEMailAddress()) ? $user->getEMailAddress() : '';
+			$decryptedToken = $this->crypto->decrypt($encryptedToken, $mailAddress.$this->config->getSystemValue('secret'));
+		} catch (\Exception $e) {
+			throw new \Exception($this->l10n->t('Couldn\'t reset password because the token is invalid'));
+		}
 
-		$splittedToken = explode(':', $this->config->getUserValue($userId, 'core', 'lostpassword', null));
+		$splittedToken = explode(':', $decryptedToken);
 		if(count($splittedToken) !== 2) {
 			throw new \Exception($this->l10n->t('Couldn\'t reset password because the token is invalid'));
 		}
@@ -249,11 +266,20 @@ class LostController extends Controller {
 			);
 		}
 
-		$token = $this->secureRandom->generate(21,
+		// Generate the token. It is stored encrypted in the database with the
+		// secret being the users' email address appended with the system secret.
+		// This makes the token automatically invalidate once the user changes
+		// their email address.
+		$token = $this->secureRandom->generate(
+			21,
 			ISecureRandom::CHAR_DIGITS.
 			ISecureRandom::CHAR_LOWER.
-			ISecureRandom::CHAR_UPPER);
-		$this->config->setUserValue($user, 'core', 'lostpassword', $this->timeFactory->getTime() .':'. $token);
+			ISecureRandom::CHAR_UPPER
+		);
+		$tokenValue = $this->timeFactory->getTime() .':'. $token;
+		$mailAddress = !is_null($userObject->getEMailAddress()) ? $userObject->getEMailAddress() : '';
+		$encryptedValue = $this->crypto->encrypt($tokenValue, $mailAddress.$this->config->getSystemValue('secret'));
+		$this->config->setUserValue($user, 'core', 'lostpassword', $encryptedValue);
 
 		$link = $this->urlGenerator->linkToRouteAbsolute('core.lost.resetform', array('userId' => $user, 'token' => $token));
 
diff --git a/tests/Core/Controller/LostControllerTest.php b/tests/Core/Controller/LostControllerTest.php
index 2c9b078908a4c88338033fddcf90147ef3e61eff..7860e597e307fb1f2de26a6d3fdf7fd772d783cc 100644
--- a/tests/Core/Controller/LostControllerTest.php
+++ b/tests/Core/Controller/LostControllerTest.php
@@ -32,6 +32,7 @@ use OCP\IURLGenerator;
 use OCP\IUser;
 use OCP\IUserManager;
 use OCP\Mail\IMailer;
+use OCP\Security\ICrypto;
 use OCP\Security\ISecureRandom;
 use PHPUnit_Framework_MockObject_MockObject;
 
@@ -66,6 +67,8 @@ class LostControllerTest extends \Test\TestCase {
 	private $timeFactory;
 	/** @var IRequest */
 	private $request;
+	/** @var ICrypto */
+	private $crypto;
 
 	protected function setUp() {
 		parent::setUp();
@@ -107,6 +110,7 @@ class LostControllerTest extends \Test\TestCase {
 		$this->encryptionManager->expects($this->any())
 			->method('isEnabled')
 			->willReturn(true);
+		$this->crypto = $this->createMock(ICrypto::class);
 		$this->lostController = new LostController(
 			'Core',
 			$this->request,
@@ -119,23 +123,55 @@ class LostControllerTest extends \Test\TestCase {
 			'lostpassword-noreply@localhost',
 			$this->encryptionManager,
 			$this->mailer,
-			$this->timeFactory
+			$this->timeFactory,
+			$this->crypto
 		);
 	}
 
-	public function testResetFormInvalidToken() {
+	public function testResetFormWithNotExistingUser() {
+		$userId = 'NotExistingUser';
+		$token = 'MySecretToken';
+		$this->userManager
+			->expects($this->once())
+			->method('get')
+			->with('NotExistingUser')
+			->willReturn(null);
+
+		$expectedResponse = new TemplateResponse(
+			'core',
+			'error',
+			[
+				'errors' => [
+					['error' => 'Couldn\'t reset password because the token is invalid'],
+				]
+			],
+			'guest'
+		);
+		$this->assertEquals($expectedResponse, $this->lostController->resetform($token, $userId));
+	}
+
+	public function testResetFormInvalidTokenFormatting() {
 		$userId = 'admin';
 		$token = 'MySecretToken';
-		$response = $this->lostController->resetform($token, $userId);
-		$expectedResponse = new TemplateResponse('core',
+		$user = $this->getMockBuilder('\OCP\IUser')->getMock();
+
+		$this->userManager
+			->expects($this->once())
+			->method('get')
+			->with('admin')
+			->willReturn($user);
+
+		$expectedResponse = new TemplateResponse(
+			'core',
 			'error',
 			[
 				'errors' => [
 					['error' => 'Couldn\'t reset password because the token is invalid'],
 				]
 			],
-			'guest');
-		$this->assertEquals($expectedResponse, $response);
+			'guest'
+		);
+		$this->assertEquals($expectedResponse, $this->lostController->resetform($token, $userId));
 	}
 
 	public function testResetFormInvalidTokenMatch() {