Open Brocklobsta opened 6 years ago
@yeah-mike. It worked!!! I programmed the challenge-response into the Yubikey with the Yubikey Manager, instead of the Yubikey Personalization Tool . Then protected the test database with the newly programmed Yubikey. I generated a keyfile with the challenge extracted following @WiLars' instructions, and now the database can be decrypted with the password and the newly generated keyfile.
So we could say the Yubikey Manager and the Yubikey Personalization Tool are following different algorithms to program the secret into the Yubikey. Right?
In case anybody would like to play with the database and keyfile that worked, I am attaching both in a zip file:
test-mini-with-yubikey-manager.zip
This database can be decrypted with the password "test01" and the keyfile-yubikey-manager keyfile. If you want to use Yubikey to open it, you need to program the Yubikey using the Yubikey Manager, with the secret "8313063e07fe63b474282d87870e7384bedccc9c".
I just realized that the Yubikey Personalization Tool software has a Challenge-Response Tester in its tools section.
@CueHD. Yes it does, but note if you want to make decryption with a keyfile work with the method explained earlier in this thread, you need to use the Yubikey Manager, not the Yubikey Personalization Tool.
I would also love to see that recovery feature.
It would be way more user-friendly than the above workaround. Even reprogramming a new Yubikey in case the original(s) is lost is not at the reach of all users - I know that no one in my family would be able to remember how to do that. Besides, having to wait a week (at least - imagine it happens on holiday), isn't practical either.
PS: I've been using Keepass with keechallenge the last years, but their implementation isn't optimal as it exposes the secret on the Yubikey on every unlock. So 👍 to KeepassXC for the good implementation!
I actually like the keyfile "workaround" as a recovery option for the Yubikey. It helps to keep the challenge/response secret a secret since it does not need to be inputted into KeepassXC nor stored anywhere.
My suggestion for a user-friendly recovery would be to have an option for KeepassXC to generate the keyfile. This way, there is no confusion as to what the correct response would be since KeepassXC knows exactly what the expected response is, and there is no reason to input the C/R secret anywhere.
I like that option the best @CueHD
Correct me, but the response changes everytime the challenge changes. So everytime you save the database you have to generate a new keyfile. Sounds not like a suitable solution to me.
Or did I get that wrong?
If by generating a key file you mean typing the hex response into a KeepassXC recovery input box and KeepassXC then generating the file, then that still seems too geeky to me. Extracting the challenge using a hex-editor and doing the hashing with the secret isn't accessible to most users (including me without spending lots of time on it). On top of that, many users might simply go to a web site to do the hashing, therefore having to reveal the secret on the internet. Feels to me that it's easier to change the secret on the Yubikey if someone feels uncomfortable after a recovery.
Correct me, but the response changes everytime the challenge changes. So everytime you save the database you have to generate a new keyfile. Sounds not like a suitable solution to me.
Or did I get that wrong?
The response only changes if you change the master password or the c/r secret.
@Coeos3 No, I suggest that the user should never need to type the secret nor the HEX response at all. KeepassXC has the response. It had to in order to unlock the database. At whatever point is most convenient for the software either during the unlock process or after it is open, it could generate the keyfile with the response and save it. The only thing the user would need to do is input the master password as normal and have the Yubikey available as normal.
@mrclschstr is correct, every time we save the database we generate a new seed which is what is sent as the challenge to the Yubikey. The response returned is what gets added to the master key (after being hashed). Unfortunately exporting the challenge seed will only protect you until you save the database again. I take back my endorsement.
For the curious (and also to document it a little) the call chain is as follows:
KDBX4Writer -> Database::setKey(...) -> New Seed Generated -> CompositeKey::Transform(...) -> CompositeKey::rawKey(...) -> Normal Keys Added to Hash Data -> CompositeKey::Challenge(...) -> Response from Yubikey using seed as challenge -> Add to hash data -> Perform KDF Transformation -> PHEW
**Note: for KDBX3.1 we screwed up yubikey implementation and added the response AFTER hashing the key, not as part of the overall key hash
I was unaware of the seed aspect to the challenge. In this case, I would say that it is more of a reason to enable KeepassXC to generate a recovery keyfile.
We cannot generate a recovery keyfile. It would need to contain the hmac secret which we do not have. If we had that, it wouldn't be any different from a normal keyfile.
@CueHD. Yes it does, but note if you want to make decryption with a keyfile work with the method explained earlier in this thread, you need to use the Yubikey Manager, not the Yubikey Personalization Tool.
FYI, I tested it and you get the same results with the Manager and the Personalization Tool only if you choose "variable input" when programming with the latter.
I opened an issue regarding the different behaviour of the Manager and the Personalization Tool using fixed 64 byte input. Can somebody join https://github.com/Yubico/yubikey-personalization-gui/issues/86#issuecomment-486638606? 😃
This might be the reason for the different behaviour (haven't tested it yet): https://github.com/mmcguill/Strongbox/issues/95#issuecomment-504238115
I wrote a small tool which will generate a keyfile to unlock your database, provided you have the challenge-response secret.
Can you put that in a pull request to add to our utils folder?
@droidmonkey Sure, no problem, I'll look into it in the next couple of days.
An alternative ( more compact ) way to open the KDBX4.0 database if the yubikey is lost is by producing the recovery keyfile with the help of the following Perl one liners:
$ perl -e 'use Digest::HMAC_SHA1 qw(hmac_sha1_hex);open $fh,"<:raw","NewDatabase.kdbx";seek $fh,0xC5,0;read $fh,$ch,32;print hmac_sha1_hex($ch,pack("H*","0102030405060708091011121314151617181920")),"\n"'
c161f2f84002033cef4767cc42bf3de92aa08bd2
* to actually create the keyfile:
$ perl -e 'use Digest::HMAC_SHA1 qw(hmac_sha1);open $fh,"<:raw","NewDatabase.kdbx";seek $fh,0xC5,0;read $fh,$ch,32;print hmac_sha1($ch,pack("H*","0102030405060708091011121314151617181920"))'>keyfile
* to check that the keyfile has been written properly:
$ hexdump -C keyfile 00000000 c1 61 f2 f8 40 02 03 3c ef 47 67 cc 42 bf 3d e9 |.a..@..<.Gg.B.=.| 00000010 2a a0 8b d2 |*...| 00000014
@christi-t I don't think this will work under all circumstances, since the address of the seed is not fixed at 0xC5. For example, it's different when you save a database with keepass2android.
@christi-t I don't think this will work under all circumstances, since the address of the seed is not fixed at 0xC5. For example, it's different when you save a database with keepass2android.
@jeinwag You are right. The general form of the command is:
perl -e 'use Digest::HMAC_SHA1 qw(hmac_sha1);open $fh,"<:raw","<db_file>";seek $fh,<offset>,0;read $fh,$ch,<challenge_length>;print hmac_sha1($ch,pack("H*","<secret>"))'>keyfile
where:
Is there a procedure to get the challenge offset?
Is there a procedure to get the challenge offset?
@cristi-t You'll need to to read and interpret the header of the password database, that's what my little tool does.
Using keepassxc/utils/keepassxc-cr-recovery
from the develop
branch is producing an unexpected error:
$ ./keepassxc-cr-recovery ./Password.kdbx ./temp-key
Secret: <challenge-response secret>
couldn't read challenge: unexpected EOF
Note: I'm able to successfully authenticate with my password and challenge-response slot using a Yubikey. I'm testing the disaster recovery procedures.
Has something changed to the header of the DB that alters how keepassxc-cr-recovery
identifies some file details? If not, should this work?
My KeePassXC details:
KeePassXC - Version 2.4.3
Revision: 5d6ef0c
Qt 5.12.4
Debugging mode is disabled.
Operating system: Ubuntu 19.10
CPU architecture: x86_64
Kernel: linux 5.3.0-46-generic
Enabled extensions:
- Auto-Type
- Browser Integration
- SSH Agent
- KeeShare (only unsigned sharing)
- YubiKey
Cryptographic libraries:
libgcrypt 1.8.4
Are you using kdbx4 database?
No, I wasn't. Updating to kdbx4 fixed it, and I can login with the utility.
Should everyone be on kdbx4 (unless they have some client reason not to) or should I update the docs to mention when keepassxc-cr-recovery
is available?
Everyone should be using kdbx4, there is no reason not to.
We should ask users to upgrade in 2.6.
.
Does KeePassXC look for a Yubikey specifically when looking for challenge-response device, either by vendor code in an AID, or only on a specific USB interface? For motivation, there is JavaCard applet https://github.com/arekinath/YkOtpApplet that achieves the same goal as the Yubikey with KeePassXC:
This is a JavaCard applet that emulates the HMAC challenge-response functionality of the Yubikey NEO/4. It presents the same interface that a real Yubikey presents over CCID (i.e. this applet does not have any HID features).
I can think of two options:
There are mentions in other issues of Nitrokey HSM & PKCS#11 support as well, which would probably be related, although the tokens made available though cryptoki would be different than the OTP applet services.
Is one of the methods preferred, unfeasible, or something else?
Note: keepassxc/utils/keepassxc-cr-recovery
still works - but this would enable security key backups.
I have no interest in supporting additional hardware tokens at this time. PKCS#11, yes.
The repair feature in keepass doesn't actually do anything. You must have corrupted your key file or wiped your yubikey, that would explain why it doesn't work in previous saves either. Highly highly unlikely your actual database is corrupt.
Are you saving your database to a USB drive? That has been known to corrupt databases before.
We don't hold any locks on files. The only time you can't touch a file is during open or saving, otherwise the file is not accessed at all.
Is there any way to use keepassxc/utils/keepassxc-cr-recovery
if I'm already using a keyfile (and a password)
Unfortunately, no.
Turns out it was quite easy to implement loading a 2nd keyfile. In case somebody else wants to restore access using the yubikey secrect, with an existing keyfile, this is how i've done it
src/cli/keepassxc-cli export -k <original keyfile> <XXX.kdbx>
to get the whole content printed to stdout. Note that in my version i had to place the keyfile generated in step 1 at /keyfile2.key
because i hardcoded that path.I would like to have a recovery feature officially implemented (or the ability to officially load two keyfiles with the cli version + this procedure well documented) because imho one of the most important things is allowing to restore access if you lose or forget a key.
Cool fix!
Just in case someone tries to recover a database with the go
package in keepassxc/utils/keepassxc-cr-recovery
, it seems there is a typo when computing the padding of the challenge (why is this padding necessary in the first place?).
Instead of 64
bytes it should be 32
on lines:
https://github.com/keepassxreboot/keepassxc/blob/a472ef8a931dd64990d7f735394e949638e880d5/utils/keepassxc-cr-recovery/main.go#L172-L178
Tested and working on my current kdbx4
database.
I recently debugged that part with someone in the chat and we found a few bugs or oversights in the implementation. I think they wanted to file a pull request, not sure what came of it. The padding is necessary for challenges of arbitrary length. How these are handled depends on how you programmed your YubiKey. There are two modes, fixed and variable, though the new management tool exposes only one to the user.
I created a static server-less HTML version of the cr-recovery tool, EtaoinWu/keepassxc-cr-recovery.html, for people (like me) who do not want to build the official go version, and/or want to run it on a mobile device without shell access. Tested with my own database.
It's also deployed on cloudflare pages, though you have to use the internet version at your own risk.
For everyone, like me, landing on this issue because the recovery tool of choice isn't working for them. Here is my summary of analyzing the situation.
Why is it like this?
Is it possible to use the Yubikey challenge-response secret (hex string) to decrypt a KeePassXC database using the KeePassXC yubichallenge implementation? I like how you guys implement the Yubichallenge btw, it is much closer to a true 2fa.
Expected Behavior
Have some way to enter the yubikey challenge-response secret when decrypting the database
Current Behavior
No option to input challenge-response secret
Possible Solution
Add a "Recovery" box to the challenge-response area that allows a hex string to be entered and used for the challenge response computation.
Steps to Reproduce (for bugs)
1: Create a database using Yubikey challenge-response (save the secret used the configure the yubikey) 2: try and decrypt the database without the use of the yubikey and only the secret.
Context
Basically since I own a Yubikey 4 and not a NEO variant, I am unable to use the Yubichallenge app to decrypt my database since it is not possible to perform a challenge-response over a USB connection with android at the time of this message. My solution to save my Yubikey secret to an encrypted android file storage and copy and paste when I need to decrypt my database.
Debug Info
KeePassXC - 2.3.1 Revision: REVISION
Libraries:
Operating system: Windows CPU architecture: Intel x64/x86 Kernel: Win10
Enabled extensions: