keepassxreboot / keepassxc

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

Use Yubikey challenge-response secret to decrypt database #1734

Open Brocklobsta opened 6 years ago

Brocklobsta commented 6 years ago

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:

droidmonkey commented 6 years ago

This would offer no additional protection over a secure master password. The whole point of the yubikey is to be a second factor. Recommend buying a Neo.

If you must use this method, just append the yubikey hex to your master password. It has the same logical effect.

Brocklobsta commented 6 years ago

Hey droidmonkey,

This would be useful in the situation where a yubikey is lost, but the user saved the secret.

droidmonkey commented 6 years ago

Interesting scenario

TheZ3ro commented 6 years ago

This would be useful in the situation where a yubikey is lost, but the user saved the secret.

Note: If you have another yubikey you can use the saved secret on that as well.

Brocklobsta commented 6 years ago

Yeah, I agree. That is the only solution. That is a $40 and week of shipping solution though.

CueHD commented 6 years ago

This would be useful in the situation where a yubikey is lost, but the user saved the secret.

Try this with your secret key: https://www.freeformatter.com/hmac-generator.html If it works, you have a way back into your database in case of a lost YubiKey.

If anything regarding this were integrated into KeepassXC, I would prefer a Challenge-Response generator that uses the inputted secret key. This keeps the superior method of using the response instead of the secret while providing an integrated method of recovery.

TheZ3ro commented 6 years ago

@CueHD it's exactly what I was thinking. Adding a dummy yubikey that will emulate the challenge-response and use the response like KeePassXC is already doing now

Brocklobsta commented 6 years ago

@CueHD

So what you are saying is for me to hash the database (SHA-1?) and then use that string and my secret to compute the HMAC using the website (https://www.freeformatter.com/hmac-generator.html).

Now with the HMAC string computed, do I prepend or append this string to my password? Is this string case-sensitive?

droidmonkey commented 6 years ago

Appending it to your password "should" work.

Brocklobsta commented 6 years ago

I am unsuccessful in decrypting my database with the following procedure:

  1. Perform SHA1 on the database file (used sha1sum command)
  2. Generate HMAC-SHA1 response using the Yubikey Personalization Tool's Challenge-Response Tester.
  3. Append response to Password in the Password box (Key file and Challenge Response left unchecked).

It looks like the strings are case sensitive, so I have been using all lowercase.

Brocklobsta commented 6 years ago

@droidmonkey, @CueHD , @TheZ3ro

So far I have been unsuccessful in decrypting my database with a manual challenge-response. Could you guys try this test on your end? I think my hex values are being interpreted as base64 so I'm getting different responses based on the case of my A-F values. The Yubikey Personalization tool has a challenge-response tool that should be useful.

droidmonkey commented 6 years ago

As this point you would have had your shiny new yubikey by now. :grin:

I do not have any free time this week (or recently), this is a complex problem.

Quick question, is your database still on kdbx3? If so then appending to the password will not work.

TheZ3ro commented 6 years ago

I think we should add this feature to the cli version, I don't really see much usage for this in the desktop version but maybe can be useful in cli to recover broken database or things like that.

I'm referring to this proposal -> https://github.com/keepassxreboot/keepassxc/issues/1734#issuecomment-376345124

droidmonkey commented 6 years ago

Yeah i agree with this

Brocklobsta commented 6 years ago

Hey @droidmonkey,

I was indeed using a 3.1 database. I switched to .kdbx 4 and am now getting an HMAC mismatch error (sha256sum my database and use that 64char output as the challenge. Appended that response to my password). I agree that a CLI interface will do the trick, but a checkbox and secret field wouldn't hurt. Honestly some documentation on how to manually compute the response and how to use that to unlock the database would suffice as well.

vronp commented 6 years ago

I'm new to KP but have a couple comments. A "recovery" mode would be very nice IMO just like the feature shown in this version of KP: http://www.kahusecurity.com/2014/11/securing-keepass-with-a-second-factor/

Also, for what it's worth, I setup a Neo with KPXC and it works fine. I had 3 Yubikey Standard keys laying around so I tried to turn one of them into a backup. None of the 3 generate the same string. I'm quite sure I'm doing everything right. Scratching my head on this and I opened a ticket with Yubico. I'll let everyone know what they have to say.

A backup Neo apparently is a solution but it shouldn't be required IMO.

TheZ3ro commented 6 years ago

None of the 3 generate the same string.

You don't have to "generate" a new secret, you must set as secret the one you generated in your primary Yubikey you registered in KPXC (the Neo I guess)

WiLars commented 6 years ago

Hi everyone, i found this post, because i was interested in being able to decrypt my database if my yubikey was lost, before i encrypted my real database using challenge response. Because i tried the suggestions above and it didn't work for my testdatabase (aes and argon2), and didn't really make much sense of the source code, i logged the communication of keepassxc and the yubikey with wireshark: what i found out this way is the following:

I don't know if there is still interest in this, but maybe I save some people the time trying this themselves.

Apart from that, thanks for all the work, I am really glad keepassxc exists!

droidmonkey commented 6 years ago

The best (and probably only) way to truly prevent issues when you lose or destroy your yubikey is to create two and store the other in a safe. Other than that, printing the csv output after creating your CR load will allow you to recreate the key with a new one.

WiLars commented 6 years ago

Thank you for the fast response! I'm afraid it is really the only solution, but i was hopeful to save the 50€ :D

droidmonkey commented 6 years ago

Its a hardware key for a reason :wink:

WiLars commented 6 years ago

I have found a way to decrypt the yubikey challenge-response emcrypted database without a yubikey:

  1. obtain the challenge: -opening the database file with a hex editor you'll find the challenge from bytes 0xc5 to 0xe4 for a database with argon2 edit: corrected the address -for a keepass 3.1 aes-kdf encrpyted file i found it at 0x2b (but i'm not sure if you can open the database with it, because the internal mechanisms of working with the response seem to be different. didn't try because it's not relevant to me)

  2. calculate the response with an online tool (hmac-sha1) -note: you need to know your secret, obviously, so make sure to save it somewhere save, when programming the yubikey. -set everything in the tool to hex, the key must be entered without spaces.

  3. using a hex editor enter the bytes you get as the response and save as a file.

  4. open keepassxc, enter your password and take the file as the keyfile. -appending the response to your password does noes not work, if i understood correctly, because there is some hashing involved in combining the keys.

  5. enjoy your database despite having lost your yubikey.

Of course, I can't guarantee that this always works, but for me it's good enough to not buy a second yubikey as a backup. I think it's more a possibility to access your database while waiting for the shipment of a new yubikey.

seatedscribe commented 6 years ago

Wow, so basically you defiled the very meaning for a piece of hardware! :)

On Sun, 26 Aug 2018, 12:38 WiLars, notifications@github.com wrote:

I have found a way to decrypt the yubikey challenge-response emcrypted database without a yubikey:

1.

obtain the challenge: -opening the database file with a hex editor you'll find the challenge from bytes 0xc5 to 0x4e for a database with argon2 -for a keepass 3.1 aes-kdf encrpyted file i found it at 0x2b (but i'm not sure if you can open the database with it, because the internal mechanisms of working with the response seem to be different. didn't try because it's not relevant to me) 2.

calculate the response with an online tool https://www.liavaag.org/English/SHA-Generator/HMAC/ (hmac-sha1) -note: you need to know your secret, obviously, so make sure to save it somewhere save, when programming the yubikey. -set everything in the tool to hex, the key must be entered without spaces. 3.

using a hex editor enter the bytes you get as the response and save as a file. 4.

open keepassxc, enter your password and take the file as the keyfile. -appending the response to your password does noes not work, if i understood correctly, because there is some hashing involved in combining the keys. 5.

enjoy your database despite having lost your yubikey.

Of course, I can't guarantee that this always works, but for me it's good enough to not buy a second yubikey as a backup. I think it's more a possibility to access your database while waiting for the shipment of a new yubikey.

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/keepassxreboot/keepassxc/issues/1734#issuecomment-416029033, or mute the thread https://github.com/notifications/unsubscribe-auth/AMqpZKW8Skohp34IuGztORKG_VGiGnL1ks5uUnqhgaJpZM4Sskei .

phoerious commented 6 years ago

Well, it's just a piece if secret binary code. It's more secure to have dedicated hardware deliver it, but you can also do it in software.

WiLars commented 6 years ago

I think if you have your binary secret in a safe and only offline it is nearly as save, as if you had a second yubikey in there. Of course in that case you can not be sure if it has been duplicated, which can't be done with the yubikey afiak. For safety reasons you should always be sure to delete the yubikey config file after programming, because the secret is saved in there.

CueHD commented 6 years ago

Great find WiLars. I think that being able to use the keyfile is a perfect recovery option. The only hassle is that one would need to generate a new one every time the master password is changed.

I also like that it is the response instead of the secret that needs to be in the keyfile. This keeps the secret safe in the YubiKey.

yeah-mike commented 6 years ago

I have found a way to decrypt the yubikey challenge-response emcrypted database without a yubikey:

  1. obtain the challenge: -opening the database file with a hex editor you'll find the challenge from bytes 0xc5 to 0x4e for a database with argon2 -for a keepass 3.1 aes-kdf encrpyted file i found it at 0x2b (but i'm not sure if you can open the database with it, because the internal mechanisms of working with the response seem to be different. didn't try because it's not relevant to me)
  2. calculate the response with an online tool (hmac-sha1) -note: you need to know your secret, obviously, so make sure to save it somewhere save, when programming the yubikey. -set everything in the tool to hex, the key must be entered without spaces.
  3. using a hex editor enter the bytes you get as the response and save as a file.
  4. open keepassxc, enter your password and take the file as the keyfile. -appending the response to your password does noes not work, if i understood correctly, because there is some hashing involved in combining the keys.
  5. enjoy your database despite having lost your yubikey.

Of course, I can't guarantee that this always works, but for me it's good enough to not buy a second yubikey as a backup. I think it's more a possibility to access your database while waiting for the shipment of a new yubikey.

Hi Wilars,

Just wondering if this is recovery procedure is still working for you?

  1. I installed KeepassXC 2.3.4 today and created a new database using argon2 as the KDF.
  2. I set the master key as Challenge-Response using my Yubikey (with known secret)
  3. I opened the database with a hex editor and copied the bytes 0xc5 to 0xe4 (not sure if your post contained a typo?)
  4. After running through the remainder of the steps to generate a key file, I sget the error "Wrong key or database file is corrupt. (HMAC mismatch)" when I try to open the database with my key file.

Any suggestions?

WiLars commented 6 years ago

Hi yeah-mike, I am currently using Keepassxc 2.3.3 and could just verify the above method. You are of course right: The challenge is 0xc5 to 0xe4, so 32 bytes.

Have you used a password or only the Yubikey? Without a password I was not able to open the database. In that case the challenge is from 0x29 to 0x48 (only tried it with one file). I was able to calculate the correct response (as verified by wireshark), however I was not able to open the database by using a keyfile. I think because of the way the masterkey is calculated from the different components, it is not possible to open the database with a keyfile in this case. Even if it was possible to open the Database this way, I strongly advise to use a password, otherwise what is the point of a "second" factor?

0x696c4f commented 5 years ago

I wrote a bash script to automate this. Not beautiful but working :)

droidmonkey commented 5 years ago

Please post as a gist, thank you.

Sbgodin commented 5 years ago

@0x696c4f Very nice work! Exactly what I was looking for: a way to recover quickly a file locked by a (lost) Yubikey using the (stored in a safe place) secret.

The good thing would be to have an option to open files directly with the secret.

pgalves commented 5 years ago

I once did some basic app to decode a keepassx yubikey protected database having the yubikey chalenge-response backup key: https://github.com/kylemanna/keepassx/pull/6.

ananta-dev commented 5 years ago

I have tried the solutions offered in this thread, but could not decypher a simple new kdbx database protected with Yubikey challenge-response, with a Yubikey NEO.

See attached:

What am I doing wrong? Any ideas?

test mini.zip

phoerious commented 5 years ago

Replacing the YubiKey with a key file only works for KDBX4 and if you are not using a key file already.

ananta-dev commented 5 years ago

Hi phoerius. As shown visually in the word file in the zip file attached to my previous comment, the database is Argon2 (KDBX 4), as recommended in this thread.

I forgot to mention that I am using KeePassXC 2.3.4.

DatabaseSettings-KeepassXCVersion

Also, as explained in the word file, I am not using a keyfile to protect the database. I am protecting it with short password ("test01") and yubikey NEO with challenge response mode HMAC-SHA1, fixed 64 byte input, with the following secret:

Secret used for Yubikey: 83 13 06 3e 07 fe 63 b4 74 28 2d 87 87 0e 73 84 be dc cc 9c Secret Without spaces:
8313063e07fe63b474282d87870e7384bedccc9c

When I open the database with a Hex editor I find the following challenge:

The challenge appears to be: cb d2 57 0c 00 35 1c c5 a1 96 55 1d 48 b7 0e 20 6b 85 75 76 87 44 4c 4d ff 37 4e dc d4 31 ac a4

Challenge without blanks: cbd2570c00351cc5a196551d48b70e206b85757687444c4dff374edcd431aca4

I am using this online tool with SHA1 to calculate the response with the above challenge and secret: https://www.liavaag.org/English/SHA-Generator/HMAC/

I obtain the following response: 0c289d895c44d16ddc390c5cf353d207676c3f6e

As explained in the word file attached to my previous comment, I obtain the same response with the script file provided by 0x696c4f, and when I create a file with the response and try to open the database with the password "test01" and the keyfile thus obtained, I get an error message "HMAC mismatch".

ananta-dev commented 5 years ago

Update: I noticed WiLars mentioned he was using KeepassXC 2.3.3. So I tried the same with KeePassXC 2.3.3 and got the same result: HMAC mismatch.

Oh well. it is not working for me. I wish I could find the way to decrypt using the secret without a Yubikey. It is not so much about losing the Yubikey. I have two Yubikeys NEO: one that I keep in safe place at home and one that I carry with me to work. The problem is sometimes I forget to take the Yubikey and then I do not have access to my passwords at work, which can be a problem.

Until I find a solution I have decided to have a second copy of the database protected with a password and keyfile, but that's not a good solution, as I have to keep making copies of the first Yubikey protected database and changing the protection on the copy, as soon as I add a new password. It is just not convenient at all. It is a pain.

ananta-dev commented 5 years ago

I also tried the other tool mentioned earlier in this thread to calculate response: https://www.freeformatter.com/hmac-generator.html

The response obtained is different from the one generated by the other tool (https://www.liavaag.org/English/SHA-Generator/HMAC/): 7ecc13c7f32cda5bd5b2dbadd77cbf493b3e66f3

This response, when entered into hex editor and saved also did not work to open the database in KeePassXC 2.3.3: HMAC mismatch.

This is what I did:

Capture

Capture2

0x696c4f commented 5 years ago

Maybe you could try to record the challenge and the response using Wireshark to see whether we're starting with the wrong challenge or if we are simply getting a wrong response.

ananta-dev commented 5 years ago

OK, I downloaded Wireshark yesterday, but I still had not installed it. I will give it a try. Do you know of a good tutorial to do what you are saying?

ananta-dev commented 5 years ago

I am not sure I am using Wireshark properly, but I obtained the attached capture while opening the test database with password and yubikey.

capture2.zip

Do you see the challenge and response there? Where exactly?

0x696c4f commented 5 years ago

@WiLars How exactly did you extract the challenge?

And I had another idea: What is the result when you put the challenge (or what we expect to be the challenge) into the Challenge-Response mode from YubiKey Personalization Tool (under Tools -> Challenge-Response)

ananta-dev commented 5 years ago

I tried the Yubikey Challenge-Response Tester. I got this response, which is different from previously calculate responses: 76661f2a034a67f1361daad513eeec038a771c3e

I am confused... Why am I getting three different responses, depending on the tool used? This cannot be right.

Challenge-Response Tester

And this one also did not work to open the file with password and keyfile.

ts-mk commented 5 years ago

@freenrg I think your confusion might be due to how the input and key is treated (TEXT vs HEX). Here's some Python3 code that matches what Yubikey Challenge-Response Tester produces:

import hashlib
import hmac

def hmac_sha1(message, hex_key):
    key = bytes.fromhex(hex_key)
    message = bytes(message, 'UTF-8')

    return hmac.new(key, message, hashlib.sha1).hexdigest()

print(hmac_sha1('test', 'YOUR_HEX_SECRET'))

It also matches what https://www.liavaag.org/English/SHA-Generator/HMAC/ produces with input type set to TEXT and key type set to HEX.

0x696c4f commented 5 years ago

@freenrg I'm pretty sure that the challenge is wrong but I have no clue why.

ananta-dev commented 5 years ago

@ts-mk. Thanks for pointing that out. I think the challenge I extracted from the database and I am entering into these tools is Hex. Therefore, if the Yubikey Challenge-Response Tester expects Text it would not be very useful in this case, right?

I have tried converting to TEXT before entering it into the Yubikey tool but it seems a difficult task, as it contains some null characters, 00h. In any case, that does not seem like the most promising course of action.

ananta-dev commented 5 years ago

@0x696c4f. OK, what to do? Did you see the Wireshark capture I posted? Do you know how to extract the actual challenge from that file?

What else can be tried to find out what the actual challenge is?

ts-mk commented 5 years ago

@freenrg Yeah, I think you should give up on the Yubikey's tool. It's good only for confirmation that you are getting the same result for text. With some coding you would have all the freedom needed to get input/output as needed.

I've played with this in the past for a brief moment and would give it another look if @WiLars confirms how the challenge is supposed to be extracted.

yeah-mike commented 5 years ago

I have tried the solutions offered in this thread, but could not decypher a simple new kdbx database protected with Yubikey challenge-response, with a Yubikey NEO.

See attached:

  • Database
  • text file with secret used to program Yubikey
  • Word file with the steps taken
  • Keyfile generated, which did not work.

What am I doing wrong? Any ideas?

test mini.zip

You'll notice from my post above I couldn't get it working, either. Eventually I got it working by programming my yubikey using Yubikey Manager (not Yubikey Personalization Tool). Not sure if this will solve your problem, but worth a shot?

ananta-dev commented 5 years ago

@yeah-mike. Interesting! And what exactly did you do with the Yubikey Manager?

yeah-mike commented 5 years ago

@yeah-mike. Interesting! And what exactly did you do with the Yubikey Manager?

  • text file with secret used to program Yubikey

I used Yubikey Manager (instead of Yubikey Personalization Tool) to my program my Yubikey with the secret. If you are attempting this, you should save a decrypted copy of your KeePass database first to keep as a backup.