keepassxreboot / keepassxc

KeePassXC is a cross-platform community-driven port of the Windows application “Keepass Password Safe”.
https://keepassxc.org/
Other
21.42k stars 1.48k forks source link

Add support for hmac-secret FIDO2 extension #3560

Open prusnak opened 5 years ago

prusnak commented 5 years ago

FIDO2 standard (the superset of the older U2F standard) includes hmac-secret extension introducing behaviour similar to older Yubikey HMAC-SHA1 Challenge-Response merged in https://github.com/keepassxreboot/keepassxc/pull/127 but much more universal as FIDO2 is an open standard.

We could try to expand the current Challenge-Response implementation in KeePassXC to cover this too (using libfido2) which will make KeePassXC compatible with any FIDO2 dongle.

This will satisfy https://github.com/keepassxreboot/keepassxc/issues/3450 and any other vendor-specific requests in the future.

gbdlin commented 3 years ago

I see there is some confusion how to approach this implementation, so I've took some questions or doubts and I'll try to answer some of them.

Can hmac-secret be used without resident credential?
Yes. It doesn't need resident credential. Even when FIDO2 implementation doesn't store non-resident credentials in memory, it can still be used, just like private key for specific credential doesn't have to be stored. It can be reproducibely derived from master key, just like private key is.

Is there any reason to use resident credential?
No. There is no gain from that. KeepassXC should store all the information somewhere (unencrypted) that can be used to fetch correct credential from the device. Preferably, there should be more than one slot for that, so multiple tokens can be enrolled, as there is no way to enroll multiple tokens so they return the same hmac-secret result. Even using resident credentials.

Is there any reason not to use resident credential? Yes. The main one is: limited memory of hardware tokens. Maximum number of stored credentials is not very high, so we should avoid wasting that. There is also 2nd issue: if malicious party will get access to the token, a list of all resident credentials can be read from many of them, if they are not secured by pin. This may lead to discovering that this key can unlock a specific container, without having access to one simultaneously.

Is there any other way to use FIDO2 for encryption? Probably not... For sure there is no better one. We can't use non-resident credentials challenge, as calculating the response involves a counter which is kept internally in hardware token. This makes the response unpredictable. We can, theoretically, store some static password in resident credential data, but this should be avoided, as the storage for those may be insecure in some implementations. It is for sure not designed for storing any secrets. hmac-secret extension is the best choice here.

Also, I would like to state my own opinion on some facts and decisions. First of all, should we wait for Microsoft to fix the current with libfido2 on Windows? We have those options:

  1. Wait for this issue to be resolved either by Microsoft or in libfido2 itself
  2. Implement the feature using libfido2 right now and either don't support it for now or require administrative privileges for it on affected Windows versions
  3. Implement the feature using libfido2 on other platforms and use Microsoft's API on Windows.

We don't have any gain from the 1st approach as libfido2 still has to be used for implementations on other platforms. Also, choosing between 2. and 3. is not blocking the implementation using libfido2, so we can just do it and worry about making it work on Windows in the meantime.

As for the actual implementation, I'm pretty sure it should work just like the yubikey's hmac-sha1 integration works right now, except it uses longer key (hmac-secret it is implemented using sha256 instead of sha1afaik) and there should be support for multiple hardware tokens, as this is not possible in secure device to clone the credential in a way that 2 keys will be producing the same output.

My1 commented 3 years ago

@gbdlin if it doesnt need RKs that's cool, you have sources tho?

because this sounds a lot like it would at least per the spec. https://github.com/keepassxreboot/keepassxc/issues/3560#issuecomment-751276399

for multiple key slots I am 100% in favor, and I agree that there is borderline no way to get anything static back from fido2, especially in a secure manner apart from hmac-secret. also due to how hmac secret works you could even rekey the slot from time to time without needing a new credential

tmthrgd commented 3 years ago

Just to chime in here, I’ve needed hmac-secret which isn’t supported on Windows. I emailed fido-dev@Microsoft and after explaining my use case I was told “We will triage the request and get back to you.” I’ll try and remember to update this thread whenever I hear back. With any luck a future version of Windows will add support, but there’s nothing you can do for now except run things as admin.

As for resident credentials, hmac-secret is fully useable without them. Whatever secret the Authenticator uses is part of the retuned credential ID.

The part of the spec referenced above means the credential will use a different key if you ask for user verification or not. You have to pick one and stick to it.

My1 commented 3 years ago

@tmthrgd wait a sec Windows doesn't support hmac-secret? Windows is the entire reason it exists

tmthrgd commented 3 years ago

@tmthrgd wait a sec Windows doesn't support hmac-secret? Windows is the entire reason it exists

Windows uses hmac-secret internally, but it doesn’t expose support to any other program. The only workaround is running as admin and avoiding the WebAuthn.h API entirely.

My1 commented 3 years ago

Now that's dumb.

UT running keypass as admin has its own advantages like not being able to be accessed easily from an application that - doesn't run as admin itself (like anydesk etc)

gbdlin commented 3 years ago

@My1 look at tarinol's code snippets. They are creating non-resident credentials with hmac-secret enabled. I've tested it with Yubikey and Solokey, both are working 100% fine and returning correct results (the same output for unchanged hmac-secret challenge, different result when I change the challenge value. I've checked the docs for fido2-cred and checked the list of resident credentials stored on the Yubikey, both confirmed that this command is not creating a resident credential.

If you wonder how it works: it is probably very similar to getting private key, which you can read more here for yubikeys. hmac-secret probably just has another HMAC generation block that involves the private key, device secret and the hmac-secret challenge.

riedel commented 3 years ago

Windows uses hmac-secret internally, but it doesn’t expose support to any other program. The only workaround is running as admin and avoiding the WebAuthn.h API entirely.

@tmthrgd this is the exact reason why I stopped working on the POC above. I have also been in contact with microsoft because I was pretty p***ed to be honest. Still waiting for the promised feedback from them. They should simply implement a security policy to turn off the admin necessity. Don't think a workaround makes any sense.

ThinkChaos commented 3 years ago

@riedel any news from MS on this?

Thanks all for your work!

twistsmyth commented 3 years ago

Hello @riedel maybe post the Microsoft ticket here so we can help upvote :)

Thank you for all your hard work!

jojastahl commented 3 years ago

Maybe the credBlob extension can help in the future? Seems that MS has added support to webauthn.h for this.

My1 commented 3 years ago

interesting idea despite the obvious drawback of likely needing an RK or otherwise eating into the limited storage

prusnak commented 3 years ago

It seems seems libfido2 now supports the Windows's native WebAuthn API: https://github.com/Yubico/libfido2/pull/336

However, it does not support hmac-secret extension for now, only credProtect.

frgomes commented 3 years ago

I've found this project below which may be useful. https://github.com/MartinKolarik/KeePassFIDO2

rugk commented 3 years ago

Note that that one is for KeePass not even KeePassX, however it could maybe be used to see how the feature is implemented there. But bear in mind, it says "experimental"…

tmthrgd commented 3 years ago

It looks like Windows is finally getting hmac-secret support (not sure what release we'll see it land): microsoft/webauthn#7.

tekkenly commented 2 years ago

I just spend some time figuring out a workaround. I have a trustkey G320 fido2 USB key with fingerprint support.

I run this script background after I logged in. when an keepassxc unlock window popup, this script will trigger a fido2 authentication, I need to do the fingerprint test, then the db will be unlocked, the unlock window will be closed.

Basically, I created a fingerprint-protected credential with hmac-secret extension in the key first with the 'create' param provided. I remember the rely party and hmac-salt with a config file, then, put hmac-secret encrypted database password to the end of this file.

Every time I need to unlock keepassxc db, this script will use the hmac-salt to get the hmac-secret from the key, which can be used to unencrypt my db password, then use dbus send the password to keepassxc to unlock.

You can change the hmac-salt everytime if you want to, you just need to give your fingerprint twice. This might be fixable by doing some programming other than use libfido2 default tools, I'm not sure. But it's good enough for me now.

I saw fido2.1 will support some blob storage, I guess the encrypted key will not need to be in the config file anymore.

I'm pretty new to this encryption world, please let me know if there are problems in this method.

some background:

I'm running herbstluftwm as my window manager on an arch based linux system. So, I can use 'herbstclient --idle' to monitor if the unlock database window is poped up. I guess you can find similar stuff with your window manager.

device=/dev/hidraw1, this is my usb dev path, you can use 'fido2-token -L' to find it out if you do not like to hard code it.

I got the dbus based unlock method from this link: https://grabski.me/tech,/linux/2020/09/02/automatically-unlock-keepassxc-on-startup-and-after-lock-screen/

libfido command help: https://developers.yubico.com/libfido2/Manuals/fido2-assert.html

script:

#!/bin/bash

database='/home/test/test.kdbx'
keyfile=''

hmac_cfg='/home/test/.config/hmac'
rp='Test'
user='Test'
hash=$(dd if=/dev/urandom bs=1 count=32 | base64)
device=/dev/hidraw1

if [ "$1" = "create" ] ; then
    eval fido2-token -L -k $rp $device
    if [ $? -eq 0 ] ; then
        echo "credential already exists. remove before create."
        exit 1
    fi
    printf "$hash\n$rp\n$user\n$hash" | fido2-cred -M -rh -c 3 $device > /dev/null
    printf "$rp\n$hash\n" > $hmac_cfg
    hmac_key=$(printf "$(dd if=/dev/urandom bs=1 count=32 | base64)\n$(head -2 .config/hmac)\n" | fido2-assert -G -hr -t uv=true $device | tail -1)
    read -sp 'password:' passwd
    echo $passwd | openssl enc -aes-256-cbc -pbkdf2 -iter 100000 -salt -pass pass:$hmac_key  | base64 >> $hmac_cfg
    exit 0
fi

herbstclient --idle | while read -r hook id title; do
    case "$title" in
    "Unlock Database - KeePassXC")
        hmac_key=$(printf "$(dd if=/dev/urandom bs=1 count=32 | base64)\n$(head -2 $hmac_cfg)\n" | fido2-assert -G -hr -t uv=true $device | tail -1)
        passwd=$(tail -1 $hmac_cfg | base64 -d | openssl aes-256-cbc -d -pbkdf2 -iter 100000 -salt -pass pass:$hmac_key)
            dbus-send --print-reply --dest=org.keepassxc.KeePassXC.MainWindow /keepassxc org.keepassxc.KeePassXC.MainWindow.openDatabase \
        string:$database string:$passwd string:$keyfile
        herbstclient close $id
        ;;
    esac
done
the-argus commented 2 years ago

I have virtually no understanding of the conversation in this thread but I know that I would absolutely love to unlock my favorite FOSS password manager with my favorite FOSS hardware key (the solo key). I know that some work has been done, so please continue that and make a PR if possible!!

Like the guys at solo said: If keepass implements an open standard like fido2, everyone wins :)

tekkenly commented 2 years ago

after a recent update, the dbus interface changed. updated the script.

StarGate01 commented 1 year ago

Using the WebAuthN Windows API, hmac-secret now properly works in the the most recent version of Windows 11 according to my tests. This has also been confirmed via Email by the the Microsoft FIDO development team.

My1 commented 1 year ago

that's cool, would be awesome if the change could also see w10 rather than just W11, but it's certainly a step forward. although it was always kinda weird that it didnt support that especially as Microsoft THEMSELVES are basically the reason this exists.

ccoenen commented 1 year ago

could also see w10 rather than just W11

Absolutely, but this should not stop this issue from getting resolved for w11, in my opinion.

My1 commented 1 year ago

could also see w10 rather than just W11

Absolutely, but this should not stop this issue from getting resolved for w11, in my opinion.

As well as eg Linux where the os doesn't Butt in

bluesuncat commented 1 year ago

Could someone make a quick summary of the status of this issue please? Its quite hard to read through all this to understand where the project stands with this and what is needed to get this implemented.

Is anyone actively working on supporting hmac-secret as a replacement for the master password in keepassxc? Is there any way to donate for his feature specifically?

Just to add some context: fido2 hmac-secret has seen quite some support in other projects like predicted. Passwords on linux are no longer needed with systemd-homed allowing login and home decryption with hmac-secret compatible fido2 devices and even luks fully supports the extension for disk encryption, even preferring hmac-secret over passphrases and keyfiles.

riedel commented 1 year ago

Hi, my recollection of things: fido2 hmac-secret would be a cross-plattform way to use security keys.

The problem was basically windows, that hides fido2 behind a windows hello based webauthn API, that is controlled by Microsoft and does not proxy the full CTAP protocol and even blocks all standard ways to communicate with the device since some windows version.

Now they have implemented an API to the hmac extension, which could be used, but it will still require a bit of effort to get it run cross-plattform due to the windows quirks. However, the windows documentation has considerably improved since then so I guess it would be good time to pick it up again.

Maybe there is a cross-platform like libfido2 supporting hmac on windows by now, then IMHO this would be the best path (see my POC 3yrs ago (if this dependencency is accepted by the maintainer)

My problem is that because my solo keys were pretty much useless for me as a windows user (yes you can use them for websites, but that was not my idea when buying developer devices) and now I lost them :), so I lost them.

My1 commented 1 year ago

The problem was basically windows, that hides fido2 behind a windows hello based webauthn API, that is controlled by Microsoft and does not proxy the full CTAP protocol and even blocks all standard ways to communicate with the device since some windows version.

about 1903. I think the idea is that because you are basically blindsigning, that this adds some security to it as applications that dont run as admin, have to go through this which will show things like where it is trying to login and which application is sending the request and if it's signed, who made it.

so while I personally think this in-between being kinda annoying especially if they just block stuff, it does add some merit.

My problem is that because my solo keys were pretty much useless for me as a windows user (yes you can use them for websites, but that was not my idea when buying developer devices) and now I lost them :), so I lost them

how are they useless? I mean you could still direct-fido to them over admin, or use non-fido interfaces to do stuff, as those wouldnt be blocked.

I see you are in Europe, if you need cheap FIDO2 keys you can check out Token2, which make some of the cheapest FIDO2 devices I know of and they are in my opinion still very nice and among my favorite

gbdlin commented 1 year ago

As far as I'm aware, libfido2 exposes HMAC extension on windows as well, since version 1.11

prusnak commented 1 year ago

As far as I'm aware, libfido2 exposes HMAC extension on windows as well, since version 1.11

That's correct - I confirmed by looking into the changelog.

This is great news as it seems there are no blockers now and we can easily implement this feature via libfido2 on all OSes (Windows, macOS, Linux).

StarGate01 commented 1 year ago

Keep in mind that the HMAC-secret extension is not supported in the Windows 10 version of the Win32 WebAuthN API, only in recent versions of Windows 11.

prusnak commented 1 year ago

Keep in mind that the HMAC-secret extension is not supported in the Windows 10 version of the Win32 WebAuthN API, only in recent versions of Windows 11.

This sounds more like an oversight than intended behavior. Do you have more information about this? Will Microsoft ever backport the functionality to Windows 10 API?

My1 commented 1 year ago

Keep in mind that the HMAC-secret extension is not supported in the Windows 10 version of the Win32 WebAuthN API, only in recent versions of Windows 11.

althugh the timing of the change makes it seem more like it's already included in the base version of w11, 21h2, at worst being enabled by a minor update.

with recent version of w11 I assume you mean 22h2, as w11 only has had 2 versions yet. any chance you (or anyone for that matter) tried w10-22h2?

StarGate01 commented 1 year ago

I will reproduce the relevant exchange with fido-dev@microsoft.com :

Dear FIDO / WebAuthN Team at Microsoft,

I am working on integrating the new Windows WebAuthN API into [project].

I already managed to create FIDO2 resident key with the hmac-secret extension enabled using the API, however the response from GetAssertion does not contain the expected hmac-secret extension data. In fact, Windows does not set the hmac-secret extension identifier in the request to the authenticator, even though I specifiy in the API call to do so.

Does this extension require a specific version of Windows? Is this expected behavior, is the hmac-secret extension ignored?

Are you targeting Windows Hello or external security keys? hmac-secret is not yet supported in Windows Hello. It is supported for external security keys in latest version of Windows 11.

I am targeting external PC/SC or USB hardware authenticators, via the WebAuthN API - since third-party FIDO2/CTAP implementations require administrative permissions.

I will test the latest version of Windows 11, up until now I did my testing on Windows 10. ... I was able to confirm hmac-secret working properly on Windows 11, thank you. Is this feature something Microsoft plans to backport to Windows 10?

Sorry, I can't comment on backport/future plans.

One more thing about hmac-secret. We have one API (WebAuthNGetApiVersionNumber) which can help in figure out which features are available on which OS. So, as documented in the header, if the WebAuthNGetApiVersionNumber returns WEBAUTHN_API_VERSION_4 or above, then platform supports hmac-secret for external security keys.

My1 commented 1 year ago

I see, you know what version of w10 you used at the time? also maybe one could check insider if the Webauthn API Version was upped there already. (I have no idea how to check)

StarGate01 commented 1 year ago

I used Windows 10 22H2 (19045.2604) and Windows 11 22H2 (22621.525) respectively.

xchapron-ledger commented 1 year ago

Ledger recently published a new application for their main hardware device, making them compatible with FIDO2 protocol and supporting HMAC extension. So one more reason for Keepass to start supporting FIDO2 instead of custom mechanism !

xchapron-ledger commented 1 year ago

@my1 I saw some discussion above regarding HMAC extension and the questionned need of using RK for credentials supporting HMAC. I can confirm that there is no need to create a RK credential to use HMAC extension. As I seen in this thread, the idea is to store something in the credential which will allow the authenticator to derive the HMAC private key. And as also mentionned above, using RK credentials when not strictly needed (userless authentication) is not the best idea due to the limitation they brings.

My1 commented 1 year ago

I can confirm that there is no need to create a RK credential to use HMAC extension. As I seen in this thread, the idea is to store something in the credential which will allow the authenticator to derive the HMAC private key.

neat

Ledger recently published a new application for their main hardware device, making them compatible with FIDO2 protocol and supporting HMAC extension.

sadly only for new models only tho (I hope they bring it for the S too as that was the primary reason I got them, years worth of promises)

And as also mentionned above, using RK credentials when not strictly needed (userless authentication) is not the best idea due to the limitation they brings.

cant agree more.

anton-isidore commented 1 year ago

Hi, from the above I understand that there is some issue with implementation for Windows. As a Linux user I would kill for an option to have this at least on Linux (and Mac?).

💰 I am offering +$300 to the bounty 💰, redeemable upon release of the build that allows me to use my Trezor as a hardware key-stick using FIDO2 on Linux. Bounty will be payed in Bitcoin over Lightning (or in any shitcoin that is supported by https://fixedfloat.com/ or some other reputable swap service).

image

(My email to claim the bounty: anton.isidore@protonmail.com)

* Bounty of course applies for general implementation that works everywhere as well.

My1 commented 1 year ago

@anton-isidore I hope you have a trezor T, as the T1 currently only supports U2F, and using the same functions the trezor Passowrd manager uses would be way too specific.

Edit: although, I dunno of the Trezor T has hmac-secret on its fido2.

prusnak commented 1 year ago

Trezor T has hmac-secret on its fido2.

Yes, Trezor Model T supports FIDO2 hmac-secret extension

ashleysommer commented 1 year ago

Is anyone else interested in taking on the bounty above? I'm taking a shot at it. I don't have a Trezor, but I have a Yubikey 4C and an older Yubikey "Security Key NFC", both support FIDO2, and both have the hmac-secret extension.

With the latest version of libfido2 supporting Window's WebAuthN (Windows Hello) API, and the latest version of Windows supporting the hmac-secret extension, it seems like the roadblocks are behind us.

I have mocked up a working proof of concept in python using the fido2 python module from yubikey, and now I am working on building that functionality into KeepassXC.

My limitations being that I only have the two Yubikey devices to test with, I don't have a Trezor, and I only work on Linux, I can't test on Windows or MacOS.

In terms of implementation, there are a couple of points of concern. Firstly, KeepassXC uses the Botan library for all of it cryptographic functionality. Libfido2 uses OpenSSL for crypto. By integrating libfido2 into KeepassXC, this will pull an OpenSSL dependency into KeepassXC. That may or may not be received well. Secondly, in order to do this integration correctly, Fido2 will need to be added in a way that complements the existing Yubikey support, and doesn't replace it. That would necessitate a large refactoring of that part of the codebase, that seems out of scope for the bounty. Perhaps it can happen in two parts. First add the Fido2 integration, and secondly refactor the code.

anton-isidore commented 1 year ago

@ashleysommer Hi, I trully appreciate that you are picking up the bounty. I am happy to see the movement.

Regarding the concerns in the implementation, it must be done in a way that will be merged and integrated into standard release, so it will be supported and maintained for all future versions.

(I am however not technical enough in this topic to provide any specific opinion on the technicalities, that you have mentioned.)

robinschwab commented 1 year ago

My limitations being that I only have the two Yubikey devices to test with, I don't have a Trezor, and I only work on Linux, I can't test on Windows or MacOS.

Unfortunately a Yubikey is not optimal for testing since we already have a solution for Yubikeys. What we need is a solution for all those who cannot rely on Yubikey. A better test device would be a Neowave Badgeo since this is dual interface wireless and wired.

ashleysommer commented 1 year ago

Unfortunately a Yubikey is not optimal for testing since we already have a solution for Yubikeys.

There are many different types of Yubikeys and same have features that others don't.

For example, my cheaper Yubikey "Fido Security Key NFC" does not include the "Challenge-Response", feature, that is something only the higher-end Yubikeys support. That means it does not work with the current KeePassXC implementation. However since it supports FIDO2, it will work with the new feature. That is the one I am currently testing with.

I'm also talking with the company Hypersecu about their product Hyperfido PRO FIDO2 Titanium. It is a very low cost device (only AUD$25) that does support FIDO2 and does appear to support the hmac-secret extension. I am planning to test with that model too.

robinschwab commented 1 year ago

Just bear in mind there are other interfaces than USB. NFC is needed on smartphones and supported by many laptops. Mechanical card readers are common on most business laptops.

My1 commented 1 year ago

it's not about the security Key series being older, the "blue yubis" as I call them as they traditionally have been blue always were FIDO-only (first U2F, and later FIDO2 as well) keys and also priced lower than the "do-everything" Yubikeys (save for the Yubi-Bio which imo should be classed as a Yubico Security Key, but well ever since USB3.1 came out, naming consistancy be damned lol)

I also have a small army of different FIDO Devices which I can gladly help.

@robinschwab somewhere between almost and all FIDO Devices are USB, I literally know TWO smartcard formfactor FIDO Devices currently. equally smartcard formfactor FIDO Devices use the same protocol as NFC devices and windows treats them the same way. also as win hello does the abstraction on windows, you should have them working

ashleysommer commented 1 year ago

@My1

it's not about the security Key series being older, the "blue yubis" as I call them as they traditionally have been blue always were FIDO-only

Yes, that was bad phrasing on my part. I am aware they still sell the "security key" series. It just happens that my particular one is around 4 years old. My new Yubikey is a 4C, only a year old, so I call them "my old Yubikey" and "my new Yubikey", but I know in reality they are different product segments, and the age of them does not dictate the feature set.

@robinschwab

Just bear in mind there are other interfaces than USB. NFC is needed on smartphones and supported by many laptops.

KeepassXC does not run on Android or IOS. I don't know if any of the Linux phones have NFC. I don't think NFC is a great requirement for this feature.

robinschwab commented 1 year ago

somewhere between almost and all FIDO Devices are USB

Not true. In Switzerland the public transport ID is a FIDO2 card. So 80% of all adults have a fido2 smartcard but I guess only about 1% have a fido2 USB stick. This may be different in other countries. There is probably a chicken and the egg problem: As long as fido2 cannot be used widely many issuers of smartcards will not implement it but if the cards are not readily available some developers will say it's not worth the effort.

It's better to think about requirements prior to writing code instead of adapting existing code years later.

KeepassXC does not run on Android or IOS

Off topic, but is the X in KeepassXC not standing for cross-platform? At least this argument is not the fault of smartcards.

gbdlin commented 1 year ago

My limitations being that I only have the two Yubikey devices to test with, I don't have a Trezor, and I only work on Linux, I can't test on Windows or MacOS.

Unfortunately a Yubikey is not optimal for testing since we already have a solution for Yubikeys. What we need is a solution for all those who cannot rely on Yubikey. A better test device would be a Neowave Badgeo since this is dual interface wireless and wired.

Why does it matter for testing that there is a solution for another feature/protocol it supports? It's not like one affects how the other works, they are distinct.

There are Yubikeys with NFC support as well, if your concern is the protocol.

tsusanka commented 1 year ago

My limitations being that I only have the two Yubikey devices to test with, I don't have a Trezor, and I only work on Linux, I can't test on Windows or MacOS.

Hey @ashleysommer, how about we send you a Trezor Model T free of charge so you can get this going? I'll ping you on email to talk details 👌.