-
-
Notifications
You must be signed in to change notification settings - Fork 1.5k
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
Add support for Windows Hello #6029
Conversation
Example of how common system key storage interface could look like:
And used in the code:
The backend of the interface could be implemented via pimpl patter or singleton pattern for each platform, depending on what's needed at runtime. |
I just wanted to chime and thank you for your work on supporting Windows Hello. Can't wait to use this. |
What is the status on this? |
@fritut08 Unfortunately due to lack of time on my end the progress of this PR has stalled for some time now. I'm still planning to finish it though. Note: I'm also waiting for the #5874 to be pulled in, to rebase this PR on it. And, some further development on the platform based common key storage interface as discussed in this thread: #3337 (comment). Especially, getting something like this in: #3337 (comment), wold save this PR some troubles on how to retrieve stored keys. |
Thank you for the work. Looking forward to this features 👍 |
8c5377f
to
f0bade8
Compare
This works but is clunky to setup. I am debating doing the full "Quick Unlock" overhaul first and them incorporate the essence of this PR into that one. |
Just wondering if this will also include faceID within Windows Hello? Right now i unlock my pc + another password manger using faceid through windows hello. Any lastly this is the only missing piece for me to migrate to KeePassXC. Keep the great work guys. |
Windows Hello will accept Face or Fingerprint if you have the capability. That is on Windows side, not us. |
Thank you for the answer. Exactly! That is what i was assuming, as long as its set under windows Hello i assume it should work. But the windows look different compared to touchid....maybe there are other messages the app need to catch and act on. By the way if you want tester i can help ;) |
I want to merge this prior to the 2.7.0 release... I don't understand the layers in the credential storage. From what I gather from the code, you use the windows credential store to store an ncrypt encrypted RSA key that encrypts the password data. Is the ncrypt part necessary for windows hello or is the credential manager enough? This solution seems like overkill to store a simple pass word and retrieve it using windows hello. |
I'm always running the latest 2.7.0 pre-release when I see a new one out, and I have a Logitech Brio that I've set up with Windows Hello, so I can help test as needed with facial recog via Windows Hello. |
Where do you get this build? cant find under tags! |
https://keepassxc.org/download/ Scroll down to the |
@droidmonkey from my testing (a year ago), I couldn't get Win32 Credential API to prompt for additional authentication (WindowsHello authn) before stored credential is returned to the program which invoked This is the reason why the NCrypt (hack) is used here. I.e.: NCrypt generates MS Passport persistent encryption key (stored by the system e.g. TPM) which is used to encrypt master password, and on decryption user WindowsHello authn is required by the system to use this key. Encrypted master password is stored in windows credential store. Note, that the windows credential store is used just for convenience to mimic the KeyCredentialManager (apple keychain) but it's not necessary since it doesn't provide any extra layer of security. In practice, KPXC could also use user's local storage to store the encrypted password. |
Ok so I did read the code correctly cause it looked like a workaround. There is a direct implementation of windows hello using the api that requires use of the shared headers between .net/c++. I certainly prefer that route, but this hack does work now to provide the same experience to the end user. |
Yes, since building with msvc is now supported KeyCredentialManager could be used instead. Though I don't know what would that mean for Qt framework because WinRT will be required for this. And it won't work with MinGW compiler. Btw I forgot to mention that I haven't tested if persistent MS Passport key is only available to the current user session or to any session. The |
I did some research on the key credential manager solution and it looks very easy and promising once you get the dependencies squared away. We are permanently moving away from mingw. |
I guess in that case, it'd make sense to explore first what are the options with KeyCredentialManager before proceeding with this PR. |
Good news, I got the KeyCredentialManager functions to work and am now working to replace everything with those. |
I have a full working quick unlock using the UWP API. I am closing this PR and will open a new one with that code once I polish it up. Took about 50 lines of code, and A LOT of research 😄 |
That's awesome news! Getting native WinHello support will be a lot easier to maintain than having custom code. I'll dive into the code once you make the new PR. |
I unified the experience between Windows Hello and TouchID and rebranded both under "Quick Unlock". The code is still in flux but here is a visual preview of initial login and then subsequent unlocking. One major improvement from the TouchID experience is to disable the password field and give a hint to the user that they are using quick unlock. I also rename the Unlock button to "Quick Unlock" to reinforce that behavior. |
Might I suggest sticking to the native windows hello interface instead: Here's a screenshot from KeePass. I think sticking to the native UI would be better than rolling custom UI. Whenever you want to unlock KeePass, the native Windows Hello dialog pops up, which seamlessly integrates with the rest of the Windows 10/11 UI. |
Yes that dialog pops up when you need to authenticate. I didn't screenshot it... before you get that dialog you need to tell us you actually want to use windows hello, and be told that windows hello is configured. |
This is draft PR which adds support to store and retrieve KeePassXC database password key using Windows Credential API and Microsoft Passport Api. This feature can be used if user has set Windows Hello PIN or biometrics to unlock their account.
In essence, CNG creates RSA 2048 bit encryption key via Microsoft Passport storage provider and "locks" it on Windows Hello authenticator when key is used for decryption. Note, windows store this key either in TPM if available or is SW protected via system. This key is then used to encrypt database key, and encrypted database key is stored on windows using Credential API. The back-end was inspired by KeePassWinHello, thought temporary storage is not implemented.
On the code side, there are 3 parts:
WinHelloKeyManager
class, which is responsible for storing, authenticating and retrieving the database key.Class tries to mimics a bit C# KeyCredentialManager class
WindowsHello
class. This class acts as a "glue" code between KeePassXC code base and WinHelloKeyManager. It interacts with user and handles errors, such as error when user canceled operation or when stored key can't be decrypted for various reasons i.e. disconnected TPM chip. Class is currently not implemented in a singleton patter fashion because it needs parent widget pointer to pin GUI/Windows Hello prompt window to the app.To compile this PR it's suggested to build it on top of #5874, due to C++17 requirements (
std::wstring_view
).What is still considered to be done:
At the moment only storing key for KeePass 2 is implemented.
When KeePassXC is uninstalled it should also delete all stored encrypted database keys and encryption key.
For now you can only reset Windows Hello storage in app via Settings->Security.
WindowsHello
class should be implemented as singletonDisclaimer: If there is any bounty to be earned by this PR, it should go to the maintainers of this project!
Screenshots
Example of
WindowsHello
class handling storage error:Type of change
#2462 #3337