-
-
Notifications
You must be signed in to change notification settings - Fork 259
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Feature request: quick unlock #102
Comments
I'd also like to suggest some kind of PIN lock as an addition to the Fingerprint lock. |
I see this is an old request, but as a new user I'd really appreciate having a quick unlock like on Keepass2Android. It seems to be well thought-out: you can only use the quick unlock once you've already unlocked with the full password, and if your quick unlock fails, you are forced to unlock with the full password. Once that's done, you can use quick unlock again. |
For me this functionality is not useful for this application because the quick unlocking of KP2A implies that the data is temporarily stored in another intermediate database, which is not the case for KeePassDX. I am thinking of other methods such as PIN or patterns to get the password in the keystore (same as biometric). Recovering a password by a piece of this shorter password has no interest, put a short password as the main credential has the same effect. EDIT : After studying how K2A works, there is no intermediate database but only one parameter which indicates that an open database is locked. Other solutions are discussed later in this conversation to encrypt the database during the quick lock. |
Does that mean, the architecture of KeePassDX hinders to go the same approach as KP2A, or do you consider the approach of KP2A to be inherently insecure? I am also using a long complex passphase for my vault, and make daily usage efficient via the quickunlock feature. |
Edit : My apologies, I come back to my explanation, I wrongly thought that the operation of the K2A quick lock involved encryption. Refer to "#102 (comment)" for more information. Old response: If you want a comparison, in my mind, it's like opening a house, on the main door of the house we added big locks and we have to make lots of turns of keys.
Advanced unlock (Fingerprint recognition/Pin/Pattern in the future) uses the same feature in both apps. It is like having a muscular butler who keeps the main key on him (keystore on the device), when you ask him, he opens the door for you. Tell me if it helps to understand, obviously it only represents my vision. I am open to criticism. |
Would there be a way to store part of the password in memory, encrypted in some way? And when the user comes back and types the missing characters, the main password gets decrypted and is used to open the full database. Example: When the user comes back, ask for the Quickunlock missing chars, decrypt the first 16 chars, combine them with the QU input, and try to use that to decrypt the main db. This way, you still the cost/benefit tradeoff of the Quickunlock function, without having to reimplement the way you handle data internally. |
Well… in any case – in addition to maybe use that – you can likely use the fingerprint authentication API in new Android versions (AFAIK also works with other unlock screens) and the Android keystore, which you can configure to require user authentication and you can also enforce the time-locking mechanism there, apparently. Pretty much what we want… Disclaimer: no Android developer here |
@rugk It's already in the code https://github.com/Kunzisoft/KeePassDX/blob/master/app/src/main/java/com/kunzisoft/keepass/biometric/BiometricUnlockDatabaseHelper.kt#L63. But I have not yet managed to operate the native unlocking of Android (pin / etc). I will debug this part when I have time. |
@shadow00 I'd say this is quite a nice idea, at least in theory... Maybe this could be available as additional security option, where we can also select how many chars we should add, and which side (left or right)... |
As I said earlier, storing the main password to recover it with part of the same password has no security interest in the case of KeePassDX. It is the same as directly storing a (After if you want, we can think about storing part of the part of the part of the password part. To be able to open it with a single letter. :D It's a little joke to make you understand that it's useless. Just increase the number of derivations in the KDF setting with a small password, it will have the same effect.) |
I disagree with this statement. Perhaps you've misunderstood my suggestion: I don't mean 'store' the encrypted partial password in file storage; I mean store it in RAM while the application is open/in the background. Unlocking the db when launching the app from zero will always require the full password. This is not the same as using a n-letter password as the master password. If the full password is short (eg: 4 characters), it would be easy to just enumerate all the possible combinations. And increasing the number of iterations in the KDF to a "safe" level would mean waiting a long time every time I unlock/save the database (which becomes even longer on mobile devices that share the db with a computer). On the other hand, if the main password is long and secure (eg: 25 characters), I can keep the number of iterations down to a reasonable level (eg 1-second unlock time). Then I enable QuickUnlock and set it to 4 characters: now, if someone tries to guess the QU shortened password, they have only 1 in 624 (14.77 million) chances[1] of getting access. After they fail, the partial password gets wiped from memory and they're back to guessing the full password - which is never gonna happen with a brute-force attack. The only way to attack someone using this feature would be to extract the encrypted partial password from RAM before it gets wiped (either by fully closing the app or after a wrong guess), and try to bruteforce the QU combination - which would still take almost three months on a single machine[2]. Bonus: the length of the QU password is easily configurable in code, since all you have to do is encrypt the first [1] assuming English alphabet, uppercase, lowercase, and numbers. |
This would also give a quick access method users who don't have/don't want to use biometric unlock (at least after unlocking the db the first time). |
Indeed, we are not talking about the same thing. I understand what you mean, but the problem in this case comes from the workflow usage. We are supposed to close the main database in KeePassDX at the end of each use. So for me, putting the password in Ram is useless since it will be deleted each time. I plan to implement Ripple to close the database in case of panic and turning off the screen also closes the database.
KeePassDX never worked like this. The auto-lock has always closed the database.as I explained earlier, there is no temporary database to protect temporarily. If you want a comparison, the workflow usage is the same as KeePass on PC. There is no quick unlock like KP2A because there is no temporary database to protect. If you close the database, it is closed, it is not kept in memory. Of course I am also thinking about deleting the Keystore keys if necessary. (#437) For what you said before:
I therefore maintain what I say, if we go in this way of storing parts of passwords in KeePassDX, it will be as secure as if we used small master passwords.
You're right, it will be easy for a hacker to decode the base, so it's why I did not understand why everyone wanted this. |
Usability of course. The problem is: I cannot enter my long master password on a mobile device, each time I access just one password. And security is always a trade-off, between usability and security here. (As long as each user can choose what they want and know the security implications, it's all fine.)
Well… this comparison is like comparing Apples und Bananas. The workflows on a mobile phone vs a desktop are totally different. Also the application behaves differently. Also Android frequently kills the app.
Well… that's the problem then.
The thread model is different for both.
|
Yes this is the purpose of this discussion, find a way to quickly open a database in KeePassDX (without biometric). But the quick unlock of K2A with password part is not a technical solution here.
When I say this sentence, it is that I do not understand why the users want to stay on an unlocking solution which is not adapted to KeePassDX. There is no technical or functional reason to use an existing part of the main password in KeePassDX as advanced unlock. I prefer to think about the native Android unlocking implementation to access the keystore (schema, etc...).
By workflow, I mean of course the workflow of opening the database. The magikeyboard can be used when a database is open, that's all. But I don't understand the link with the discussion. You can open a new issue if you have a problem with the magikeyboard.
This is not normal, KeePassDX use a foreground service to not killed the app if the database is open. If you have this problem, please open an issue. There may be Android systems from manufacturers that force the application to close. There is no "semi-lock" in KeePassDX, a database is either open or closed. To implement the semi lock, we have to change the complete architecture of the app and the behavior of the lock methods, we must add another database to copy all the content of the main database which will be managed separately. If it is to have only a shorter temporary password based on a part of the main password, I do not see the interest to completely modify KeePassDX to be identical to KeePass2Android, just use K2A. (use the one that suits your needs.) KeePassDX is not made for the semi-lock. But the discussion is to find a way to open the database quickly using the Keystore on the phone without using the fingerprint (with a schema, or a PIN, etc..) Sorry, I may be misunderstanding, I still use the translation tools. |
@J-Jamet I might have not expressed myself clearly in my comment.
What I meant is actually using the Fingerprint combined with the last letters of the password. I mean I'm not aware how the Fingerprint feature works, I just assumed that it stores the password somewhere in order to decrypt the DB, and that's why I suggested what I suggested 🙂 |
This is not what I, and the OP who requested this feature, are talking about. The QuickUnlock feature in KP2A only applies after you unlock the db the first time, either by typing your full password or by using biometric authentication. When you unlock, you also choose whether to enable QuickUnlock or not. Now: you say KP2A does it by storing data in an intermediate database, and that's inefficient and would require major internal rework, which would not be good. I agree with that. This is my suggested flow for a user with QuickUnlock enabled:
[1] For better security, the KDF should include a different random salt each time this operation is performed
There is no temporary/semi-locked database in my proposal either. The database is either unlocked (when it's open), or fully locked with the full password (when the app is not running in the background AND when it gets auto-locked after the set timeout and the app is still open in the background). We're using the same name as KP2A, but the implementation I'm suggesting is fundamentally different from the way KP2A does it. Any transformation done to the user's input happens prior to the unlock function call. |
@shadow00 has perfectly the state flow concept formulated as I had it in mind, thanks a lot for making this so clear. As far as I understood by now, the proposed PIN or fingerprint "quick unlocks" all rely on the android keystore. p.s. First: thank you all for the helpful discussion, providing great critical insight into the design concepts - and the resulting challenges. |
We are mostly talking about using a substring of the password as a "reopener" - for obvious pragmatic reason (not having to ask the user to provide a re-opener pass). But in general, the "quickunlock" is just an independent key to recover a cached master passwd from application memory. From the TFA concept of "things the user knows" and "things the user has", I'd actually see the state/event, that the DB has been recently unlocked, as "something the user has". Seing it like this might make is easier to take this as a key component in a multi-path unlocking scenario to cover several multi-factor combinations. As a sidenote, my highly preferred solution for quickunlock would be a physical token (Yubikey or the like), which then could be used as a second factor in combination with a short PIN - I'd expect this should be quickest; I'd be willing to invest for a trial, if I'd only see a realistic change to get the functionality on all relevant platforms (Ubuntu, Win10, Googledroid, LineageOS, ...); as not all my devices have a (working) fingerprint scanner, referring to #106, I'd be happy to use a hardware key as the 2nd factor along with a PIN. Pragmatically, I'd wonder if it would be feasible to smoothly use a key stored on a wire-bound device, like a USB stick? If that scenario means lots of clicks, it's useless - but if it could work on my mobile device just like on my PC, with automount, it would be a great (and very cheap) thing. |
You don't have to, but it's very useful. 1. it's used anyway, already. 2. you should trust your OS anyway, but most importantly 3. the way the keystore works AFAIK is that you get an (asymmetric) encryption key from it, so you have the secret in your application anyway and encrypt your own things, … |
Okay, I can see more clearly the reasons why we don't understand each other. Finally, this is only an interpretation of the concepts. I think I have not been clear on several subjects, sorry for that, I have my nose in the code very often so it can be difficult to get out of it a few times. Keystore: @shadow00 There is a concept that is not clear: closing the application. Concretely, the closing of an android app is not so easy to define, it is not because visually it is not visible that it is closed and vice versa, it is not because we have access to variables in the app that it is open. What you suggest is to store the master key in a separate keystore stored only in RAM. Which is feasible if it is stored in the context of the application class (but no guarantee of destruction), I hadn't thought of it because simply using the Keystore on the phone was more appropriate and I didn't see the point of creating another keystore. Why? Because it is possible to delete a key from the keystore, so deleting the encrypted password in RAM after an event would be equivalent to deleting a key from the keystore of the device after the same event. Your scenario (Points 1 to 4) is already in place for fingerprints (just replace RAM with Keystore), so it would have to be adapted for other opening methods (Pattern, PIN, Passphrase or other |
I do not know if it is clearer? I try to have an objective point of view compatible with the technical needs of the app. So this is my interpretation of the solution you describe. It is never easy if the request is based on another application whose internal functioning is not identical. |
@J-Jamet sorry, I've been busy the last two days and could not reply sooner. I was not very familiar with the Android Keystore, but from what I read it should be the best place to store the encrypted master password - no need to implement your own version of the Keystore. If we encrypt our copy of the password before we place it in the Keystore, and we request the Keystore to remove it after one failed unlock attempt, I think we don't really need to require user authentication to access it. I thought that Android/Java had a method to securely wipe a variable from ram (something like Windows' SecureZeroMemory function), but it seems this does not exist in Java. Therefore, the Keystore seems to be the best place to store the encrypted password. I guess the best way to implement this would be through a Service running in the background, which gets created right after the user unlocks the database (encrypting the master password with the last n chars and then adding it to the Keystore - if the QuickUnlock feature is enabled), and gets destroyed (removing the encrypted master password from the Keystore) when the user fails the QU unlock attempt, or the application is terminated (along with all its services). |
No worries, we respond when we have time ;)
I still have to study the identification methods that I can combine with the Keystore, so I cannot answer this part for the moment but yes it is doable.
Operation is roughly similar with biometric decryption. So we have to look at which methods to reuse to add key in the Keystore.
This is where it gets complicated, because there is no event that indicates that an application is terminated (as explained earlier). When the databases are closed, there are no more services running, we must therefore consider the application closed. So the key will remain in the keystore until it is told expressly to destroy it. |
For those who have questions about how the K2A QuickUnlock works, I pushed my analysis further: The most interesting lines are:
,
and
This code partially shows how K2A works. I thought wrongly (excuse me for that, I should have pushed the analysis further) that the data was encrypted during the Quick unlock (which seemed logical to me). But by referring to the code, on K2A it's a simple variable on an open database and a visual lock so that a physical user does not access the data by the UI. (Broadcasts seem to close the activities and services related to the use of the entries, tell me if I'm wrong.) Personally, this operation does not satisfy me, because ultimately there are the same theoretical problems as what I describe in this conversation. For me, the most secure solution is still to use the idea of the salted password in the KeyStore. |
In truth, what upsets me most is that I did not understand that KeePass2Android simply did not encrypt the database during a quick lock. I do not know all the hack techniques but there are much more chances of accessing memory areas of an unencrypted database to recover passwords even if the user only has a chance by the user interface (the database is potentially always open with this technique.). It is not just a question of probability. From a theoretical point of view, if it's possible to access the memory areas (RAM) of the app (with decrypted database), it is won for the hacker. No even need to go through a decipher. I don't know if everyone has that in mind. Perhaps I was the only one who did not understand the technical functioning of the first request and that you really want to rapid use on a database that is always open but visually inaccessible? |
Holy shit, I thought K2A actually encrypted the database when it was locked with QuickUnlock, not just hidden away from user access! If I had known that was how K2A actually did this, I would have never used that feature.
No, that is definitely not something I had in mind either. I assumed it was actually encrypted, and that it used some method like the one I suggested to quickly unlock the db without asking for the full password. In terms of "observable behaviour" it looks the same to the user, but my proposal actually requires encrypting the database while it's locked with QuickUnlock - not just hiding access away from the user interface.
100% agree. Please implement the method we've been discussing here asap - I really need a new password manager D: |
My point was when a person is very tired and sleeping, his friends can make use of his finger for first unlocking the phone and then the keepass database. In this respect quick unlock with PIN or last X characters of password is more secure than biometric unlock. By the way, is key or password saved by KeePassDX somewhere, for decrypting database using Biometric Authentication? |
@Sunnyji In this case, you want a programmed obsolescence of the biometric key. I plan to implement this feature soon. It's related to #566
The master password fingerprint is encrypted in the KeyStore with a biometric key (https://github.com/Kunzisoft/KeePassDX/blob/master/app/src/main/java/com/kunzisoft/keepass/biometric/BiometricUnlockDatabaseHelper.kt). |
I am currently developing the feature that uses the phone's credentials to unlock the database. |
Awesome! 🎉 For me this solves this issue here. 👍 |
Will there be an option to follow the same authentication flow as we discussed here? (First unlock with password only, then store the password in the keystore to allow quick unlocking, and remove any old entries if/when the app service gets killed by the system or after a failed authentication attempt) Or will this be a "permanent" method once I enable it, so anyone who knows my system pin/password/pattern could unlock my db at any time without ever knowing my db password? |
I reused the biometric workflow as it is suitable for device identification methods.
A setting will allow the keys to be invalidates after a set time for biometric and device credentials. #566 There will be no more worries at this level and will be configurable according to needs. To stop using the advanced unlock, just delete the key manually. (It was the crossed out fingerprint icon, I replaced it with a crossed out key). You must validate the advanced unlocking when you want to reuse the feature after entering your password. Which is not a problem because it is quick. Edit: After careful analysis, it appears that new Android devices apply restrictions in "receiver" for device optimization that will not allow keys to be deleted in many cases. And also to satisfy users who do not want to store encrypted content, a new method using a foreground service can be applied. |
Woohoo!! This is awesome! Can't wait to try it when it's released! |
New method : The encrypted content generated by the biometric API (also used for the device credential) will be stored temporarily in the foreground service if the setting is enabled in KeePassDX. With this behavior, the Keystore only contains random keys (generated for the temporary biometric system) and no sensitive content, so no longer needs to manage it differently for each unlocking method and no need to invalidate keys anymore #566. There will unfortunately be a notification still present, but we could use a specific channel to manually disable this notification in the OS settings. This is a not at all an obvious feature, so sorry if I test yet another solution but I prefer to test all cases to get the best result. |
I implemented the new method in a branch and it works like a charm. I am very happy. There are still some bugs to fix but I'm pretty proud of the job done. :) |
That's fantastic! Can't wait to try it! Regarding the permanent notification of the background service: KP2A has it too, and personally I don't mind it - in fact, I think it's a good way to show that the QuickUnlock service is available. I haven't noticed any significant increase in battery usage because of it. Thank you for your hard work! |
I have completed the development of the device unlock for Android M+, will be available in the next version. |
Version 2.9.5 is released, this complicated feature can now be closed! (finally) :) |
I use the Keepass2Android app and this feature make it very pleasant to use. When DB is auto lock, then you only have to type the 3 last letter of your password to unlock. I have a long pass phrase so it is really helpful.
The text was updated successfully, but these errors were encountered: