keepassxc icon indicating copy to clipboard operation
keepassxc copied to clipboard

Add QuickUnlock Feature

Open seatedscribe opened this issue 8 years ago • 94 comments

With the newest and coolest feature of passphrase generator finally merged in, I find this request even more opportune - as you could tell, I have a LONG passphrase as master key for any of my databases, so my opinion may be a little biased :smile:

A rationale for this feature request is best explained by the author of keepass2android. I use this app regularly on a daily base and could not even think of practically handling the unlock procedure without this service. Here it goes, step by step (courtesy of https://keepass2android.codeplex.com/)

You should protect your password database with a strong (i.e. random and LONG) password including upper and lower case as well as numbers and special characters. Typing such a password ~~on a mobile phone~~ every time you unlock your database is time-consuming and error-prone.

  • Use a strong password for your database
  • Load your database and type the strong password once. Enable QuickUnlock
  • The application is locked after the time specified in the settings
  • If you want to re-open your database, you can type just a few characters (by default, the last 3 characters of your password) to unlock quickly and easily!
  • If the wrong QuickUnlock key is entered, the database is locked and the full password is required to re-open

Is this safe? First: it allows you to use a really strong password, this increases safety in case someone gets your database file. Second: If ~~you loose your phone~~ someone seize your laptop and tries to open your password database, the attacker has exactly one chance to make use of QuickUnlock. When using 3 characters and assuming 70 characters in the set of possible characters, the attacker has a 0.0003% chance of opening the file. If this sounds still too much for you, choose 4 or more characters in the settings.

I am not an expert on how this should be done correctly from a crypto perspective, but I am available and open to collaborations so to have this feature implemented :white_check_mark:

seatedscribe avatar Apr 10 '17 21:04 seatedscribe

I agree that it is practical and use it myself, but it do actually makes your DB a lot less safe against a advanced attacker. The safety example is only true if you do not take cloning/imaging into account. By cloning the unit, the attacker will have a indefinite tries to enter the correct password. And as you have practically shortened your 70 character keylength down to a very weak 3 character password it will be possible to unlock the unit in a very little amount of time.

By using the quick unlock there is also a chance that the user will lock themselves out of the DB if they forget the true password and is only used to enter the short version of the full password.

I'm not against quick unlock, but I strongly believe it's critical to not mislead the user into thinking they are more or even equally secure by using it.

StefanB08 avatar Apr 11 '17 11:04 StefanB08

I think this is a good thing for an opt-in option with the ability to select the length.

Like @StefanB08 suggested, if your adversary have great capabilities this will effectively lower your security. For the average user I don't think it's a great problem so opt-in is fine by me.

Also an important side note, this option will need the master password stored in memory (for decrypting the database when the QuickUnlock is entered)

TheZ3ro avatar Apr 11 '17 16:04 TheZ3ro

I'd be much more a fan of enabling QuickUnlock with some other identifier, such as a separately-set PIN. This PIN can be a configurable length (it should probably default to 4), and can only be used to unlock the database during the current KPXC process if the database has been unlocked before -- to ensure the PIN (the "QuickUnlock passphrase") cannot be used to unlock the database from a new process / session.

This enables the ease of use of quick-unlocking a database without requiring the passphrase (or a subsection of the passphrase) to be repeatedly entered.

Windows 10 implements such a feature, where the user is only required to enter a small string of characters (a PIN in this particular case) that is - critically - not the same as their user password. This prevents keyloggers* or drive-by onlookers from being able to utilize the information they gather.

* This is assuming that the keylogger doesn't have access to the keyboard when it is entered initially.

sudoforge avatar Apr 15 '17 15:04 sudoforge

@StefanB08 I agree with you that in this scenario (a laptop in the hands of the cruel enemy) quick unlock is the least feature one wants enabled for his password manager. But at the same time we can think of alternatives, like having also a yubikey inserted which can reduce the risk of a brute force attack. As before, this should be an opt-in depending on the paranoid level of the user :smile:

@bddenhartog having a PIN unrelated to the master password reduces the attack surface. Should the PIN remain the same from session to session, or is it to be generated anew every time KXC is launched?

  • In the latter case it could be challenging (or a good memory exercise) since it changes frequently;
  • In the former case, where is it supposed to be stored in the DB? @TheZ3ro maybe KDBX4 can be extended to allow this feature? Just sayin'...

seatedscribe avatar Apr 19 '17 21:04 seatedscribe

quote @seatedscribe:

@bddenhartog having a PIN unrelated to the master password reduces the attack surface. Should the PIN remain the same from session to session, or is it to be generated anew every time KXC is launched?

  • In the latter case it could be challenging (or a good memory exercise) since it changes frequently;
  • In the former case, where is it supposed to be stored in the DB? @TheZ3ro maybe KDBX4 can be extended to allow this feature? Just sayin'...

It would definitely be most convenient to store the (non-ephemeral) PIN in the database settings; and I agree that this would be the preferred method of storage (over say, storing it on disk [permanent] or in memory [ephemeral]).

As a workaround to the current impossibility of storing the PIN in the database settings, perhaps we could read the PIN from the CLI (not unlike --pw-stdin does), and/or look for the value in a .keepassxc configuration file in the user's home directory?

sudoforge avatar Apr 19 '17 22:04 sudoforge

Implementation wise, all those options are not available to us.

We have 2 cases:

  1. Using a PIN not related to the master password (stored somewhere, doesn't matter now)
  2. Using some character from the master password

In both those cases, if the master password is not stored in memory, you won't be able to unlock the database. By having a PIN or some char of the master password you can't derive the complete master password. (The DB is directly encrypted with the masterpassword) And also if your database is locked with a Yubikey, you can't unlock it in both cases above if you don't have the Yubikey inserted.

TheZ3ro avatar Apr 20 '17 09:04 TheZ3ro

@thez3ro i believe you use the pin or last chars to encrypt the composite key in memory. Am i correct?

droidmonkey avatar Apr 20 '17 14:04 droidmonkey

@droidmonkey should be a viable option, but then you shouldn't store the PIN anywhere and decrypt on demand

TheZ3ro avatar Apr 20 '17 14:04 TheZ3ro

The pin is known by the end user thus not stored.

droidmonkey avatar Apr 20 '17 15:04 droidmonkey

@droidmonkey yes, I was clarifying this:

As a workaround to the current impossibility of storing the PIN in the database settings, perhaps we could read the PIN from the CLI (not unlike --pw-stdin does), and/or look for the value in a .keepassxc configuration file in the user's home directory?

TheZ3ro avatar Apr 20 '17 15:04 TheZ3ro

Closed accidentally, my bad. Reopened

TheZ3ro avatar Apr 20 '17 15:04 TheZ3ro

With regard to PIN QuickUnlock, I was wondering if we could somehow have TOTP QuickUnlock? That would be interesting for me. Getting a TOTP token from my phone would still be way faster than typing my full passphrase. I know since @TheZ3ro answer to my comment here that TOTP is not suitable for initial unlocking, but maybe it could be here?

ArchangeGabriel avatar Apr 29 '17 14:04 ArchangeGabriel

@ArchangeGabriel, QuickUnlock protects the master secret with the "easier" one (precisely so you don't have to type your full passphrase). You can't do that with TOTP for the reasons explained in that comment.

You may want to open a new request to have an option of not actually locking keepassxc but leaving everything in memory awaiting a TOTP token.

Keisial avatar May 04 '17 07:05 Keisial

@TheZ3ro What's the problem with storing the PIN in the database itself? It's probably less sensitive than other db contents. It could be stored with no view interface, so that brief access to an unlocked instance doesn't allow later compromises.

Keisial avatar May 04 '17 07:05 Keisial

@Keisial we don't have such a filter, all entry in the DB are displayed. We can store it like KeePassHTTP Settings but then you will need the masterpassword to access it/read it.

A viable solution can be: Store a new entry called KeePassXC QuickUnlock PIN as the masterpassword encrypted with the user-selected PIN (I will call this QuickSecret). This will be stored in the DB encrypted with the masterpassword itself. Then once the DB is unlocked for the first time the QuickSecret is loaded in memory. Whenever the DB is locked again KeePassXC will ask for the PIN, decrypt the QuickSecret to get the masterpassword and the unlock the DB. If the PIN is wrong, delete from memory the QuickSecret so an attacker has only 1 attempt.

The only problem in this setup is that what we call "masterpassword" can be: 1 password, 1 keyfile and/or 1 yubikey.

Sincerely, I don't really like adding another way to unlock my databases so I think we should get this right if users want this feature. I will look into KeePass2Android code to see their implementation.

TheZ3ro avatar May 04 '17 09:05 TheZ3ro

Any news about this?

dok18 avatar Sep 18 '17 18:09 dok18

This is a wishlist item, no plans as of right now to implement.

droidmonkey avatar Sep 18 '17 21:09 droidmonkey

I was looking into this and noticed that KeePass2Android does the QuickUnlock by asking X character from the master-password

The master-password is stored in memory in plain-text [1], the masterkey (master-password + keyfile + yubikey) is also stored in memory so it can unlock the Db just fine [2]

This implementation will not work with KeePassXC since once the user inserted his master-password, the plain-text is thrown away and only an hash of it is kept in memory. So we can't really ask for the first 10 digit of the master-password since KeePassXC doesn't have this information and can't check if it's correct. Only the full master-password hash will match.

I will think about it


[1] https://github.com/PhilippC/keepass2android/blob/17cbb754a6d46cc3dfae3399804d796014b3cddf/src/KeePassLib2Android/Keys/KcpPassword.cs#L77 [2] https://github.com/PhilippC/keepass2android/blob/4a738990ae9807bb30629df9551650e99ee82640/src/keepass2android/QuickUnlock.cs#L323

TheZ3ro avatar Jan 08 '18 23:01 TheZ3ro

once the user inserted his master-password, the plain-text is thrown away and only an hash of it is kept in memory.

What about storing the hash of the last n characters along with the hash of the full master-password? This way the quick password can be processed the same way as the full-size password... Basically I'm saying the db is protected with a master password which is a subset (last n chars) of the original, but only one attempt is permitted. Is it still too weak of an approach? (please be kind, I'm no expert here) :)

seatedscribe avatar Jan 08 '18 23:01 seatedscribe

There's another implementation where you can choose between a part of your master password or an entry in the database itself: https://github.com/JanisEst/KeePassQuickUnlock

electrofloat avatar Mar 04 '18 16:03 electrofloat

@TheZ3ro

The master-password is stored in memory in plain-text [1], the masterkey (master-password + keyfile + yubikey) is also stored in memory so it can unlock the Db just fine [2]

I don't know how did you come to a conclusion of it is stored in plain-text. The linked linked line shows: m_psPassword = new ProtectedString(true, pbPasswordUtf8); and if you go a bit further: https://github.com/PhilippC/keepass2android/blob/17cbb754a6d46cc3dfae3399804d796014b3cddf/src/KeePassLib2Android/Security/ProtectedString.cs#L175 https://github.com/PhilippC/keepass2android/blob/17cbb754a6d46cc3dfae3399804d796014b3cddf/src/KeePassLib2Android/Security/ProtectedBinary.cs#L288

So ProtectedString with utf8 byte array seems pretty much encrypted to me.

electrofloat avatar Mar 04 '18 17:03 electrofloat

The string itself may be encrypted, but the decryption key for it has to be stored in plain text. Otherwise you wouldn't be able to access the data.

phoerious avatar Mar 04 '18 17:03 phoerious

The string itself may be encrypted, but the decryption key for it has to be stored in plain text. Otherwise you wouldn't be able to access the data.

I only talked about the master-password. Which is encrypted (not may be). Though you're right about the encryption key (there are some other protections in the lib itself for Windows, but that does not matter on Android.) Also the user provided quickunlockpin can be used for the encryption key, like it is done here: https://github.com/JanisEst/KeePassQuickUnlock/blob/master/QuickUnlockProvider.cs#L135

electrofloat avatar Mar 04 '18 18:03 electrofloat

There is just no secure in-memory encryption. In-memory encryption just means that you have a key somewhere at another memory location of which you hope that an attacker has no access to it. But without proper hardware and OS support, you will never be able to properly secure it.

phoerious avatar Mar 04 '18 18:03 phoerious

Maybe the KeePassQuickUnlock author is reading this thread :stuck_out_tongue:

In May 2017 I proposed to encrypt the masterkey with the pin.

In November 2017 KeePassQuickUnlock starts encrypting the masterkey with the derived pin.

Anyway from what I can see the pin can't be used the first time you unlock a DB, am I right? It keeps in memory the PIN-encrypted version of the CompositeKey/masterkey. Then you can store it in the database itself (in the CustomData field FTW) and load it at startup as my initial proposal.

Maybe we can implement this as well, seems doable and relatively secure.

TheZ3ro avatar Mar 04 '18 20:03 TheZ3ro

Anyway from what I can see the pin can't be used the first time you unlock a DB, am I right?

Yes, at first you have to unlock with the normal method. After that you can use your quick unlock.

electrofloat avatar Mar 05 '18 10:03 electrofloat

This feature is currently the only plugin that stops me from converting everything over to KeePassXC. Quick Unlock works really well for me as my 32 character master pwd is a little cumbersome to enter, but having a four character Quick Unlock is brilliant. I can see this making KeePassXC my goto for my Chromebook in Crouton.

The Keepass2Android implemenation is great as well, but I now also use the biometrics (fingerprint) ID for quick unlock as well, not saying that this is necessary here, but this little assistance increases usability for me a lot.

Yorik-Code avatar Mar 07 '18 14:03 Yorik-Code

Hello,

I'm testing KeePassXC, since I'm starting to see a lot of references to it (I'm a long run user of KeePass, and KeePass2Android). I'm coming here, because the quick unlock is definitely one of the two missing features versus keepass (+plugins) that could make me change software.

About the security, indeed quick unlock is less secure than full unlock. BUT. Full unlock can be so painful (with long passwords, just to input passwords that are less long) that probably a lot of peopledisable auto-lock of database. Which is even far less secure in the end. In my case, I'm using a database every day at work, but it's too painful to full unlock it every few minutes (maximum value of inactivity being 9999s, so 2.5 hours, far from the 9 hours day of work).

About implementation, ideas here seem correct to me, also I'm using the two references given here (KeePassQuickUnlock and Keepass2Android) so I probably won't be of any help on this subject.

But about the quick unlock workflow, here is something that should reduce the attack possibilities: 1 - Quick unlock is not available if the database is closed 2 - On full unlock, some stuff is done and stored (from what I read, the latest option is encrypting master password with the PIN. Multiple encryption cycles could reinforce the security) 3 - On next unlock, since quick unlock data are available, the input is checked with the PIN 4 - If the input is valid, then database is unlocked with the decrypted master password 5 - If the input is wrong, quick unlock data are deleted from memory, and we're back to step 1 (number of retries may or may not be configurable. higher value means lower security)

It would also be great to have a setting to delete quick unlock data after a period of inactivity. For example, full unlock may be required every morning...

I'll be watching this issue, in the meantime I'll go back to KeePass with QuickUnlock and AutoTypeSearch (the other missing feature from KeePassXC for my usage)

Good work for the app by the way, it's less 90's than KeePass :)

Karreg avatar Aug 22 '18 07:08 Karreg

It would also be great to have a setting to delete quick unlock data after a period of inactivity. For example, full unlock may be required every morning...

I really like this proposal. Sadly implementing it is a little painful

TheZ3ro avatar Nov 30 '18 17:11 TheZ3ro

Any progress on this? Loving my keepass2android experience - wishing keepassXC would at least let me opt in.

lourivellini avatar Jul 08 '19 01:07 lourivellini