Menu

Secret used to encrypt

Guy
2015-01-07
2016-05-10
  • Guy

    Guy - 2015-01-07

    From your description of KeeChallenge at http://forum.yubico.com/viewtopic.php?f=8&t=1337? it sounds like the HMAC secret is used as the encryption key to encrypt the database. Is that correct? That makes me nervous. I'd much prefer the HMAC secret to never leave the YubiKey - especially as I might be using the HMAC challenge/response for other applications.

    Wouldn't it be better for the encryption key to be randomly generated at creation time - but for KeeChallenge to otherwise work as now. The recovery mode from the user's perspective could stay the same - user enters the secret but this is now used to generate the HMAC to decode the encryption key (alternatively the randomly generated encryption key can be shown to the user at creation time).

    Best regards,

    Guy

     
  • Ben

    Ben - 2015-01-09

    Guy, I originally shared a lot of your concerns when developing the keechallenge. You're right that recovery mode is why I went the direction I did. The architecture you suggest is feasible, but it has a vulnerability. Let's say we generate a random secret used to encrypt the keepass database each time, then we encrypt that secret using the HMAC response and store the encrypted random secret in the xml file. The problem arises if the xml file is deleted, corrupted, or otherwise compromised. If this happens, you have no way to recover the random secret and your database is permanently lost. The only way around this is to have the database encryption secret remain static. Any dynamic scheme would require the user to, at the minimum, track some kind of counter. Losing count would result in an unrecoverable database under the above scenario. This is definitely a corner-case, but I think that it's not so unlikely that I can ignore it.

    I've been very careful to take all available measures to maintain the integrity of the shared secret. Most important, it is never written to disk in any fashion. There are only a few methods that an attacker could use to gain knowledge of the secret. The simplest would be to try to break the encryption on the xml file. That threat is equivalent to breaking the either the HMAC-SHA1 or the AES256 algorithm. As long as these algorithms remain secure, an attacker cannot gain knowledge of your HMAC secret via the xml file. The other attack vectors all involve compromising the machine used to access the database. Once a machine is so severely compromised that the attacker can access the decrypted secret from application memory despite the measures I've taken to try to prevent this, it's pretty much game over.

    Sorry for the wall of text and I hope I didn't come off as lecturing. I do appreciate your concerns, but I think that the existing architecture is fully secure against all attack vectors save a completely compromised machine.
    Ben

     
  • Guy

    Guy - 2015-01-09

    Thanks for developing KeeChallenge and for your post. It certainly didn't come across as lecturing.

    If I understand the concern is the loss of the XML file containing the data required to decrypt the Keepass database?

    But surely just as the user is responsible for backing up their Keepass database then they are responsible for backing up the XML file. And in practice, this is unlikely to be arduous as both can be safely stored in the same folder?

    It is true that a compromised machine is probably the only way of getting access to the HMAC secret. However, if KeeChallenge is compromised (for whatever reason) then all other systems that I've set up to use the Neo challenge/response secret are compromised too. So if the choice is to accept that risk or backup one more file, then I'd much rather backup one more file...

    Best regards,
    Guy

     
  • Ben

    Ben - 2015-01-12

    Your point is well taken, and I definitely sympathize. Here's my thought process on this one. In my mind, the very worst case behavior for keechallenge is to expose the keepass database to an attacker. The runner up is to render the database inaccessible. When I was laying out the basic architecture I felt that even if it's a low probability event, I could entirely eliminate it via the current architecture.

    Back in the initial design phase, I was operating under the assumption that the keepass database was the ultimate goal of any attacker and that the yubikey secret had no value other than to unlock the database. I now realize that this isn't necessarily true in cases like yours.

    I've thought about this a lot over the weekend. The biggest stumbling block, apart from the risk of database loss, is that HMAC is fundamentally designed to operate using a shared secret. That is, in order to verify the MAC, you must be in possession of the secret. For keechallenge, this impacts us when we generate the challenge-response pair to use next time. As it stands, this is done locally based on our knowledge of the secret.

    The only way around this is to authenticate twice each time, once to gain access and once to generate the response for use next time. My big problem with this is the inconvenience it presents the user. It means two button presses or NFC swipes per access. It's not a huge effort, but it doubles the amount of user input required which is a significant negative for me.

    So here's where I come down on the whole thing: I think that the security risk introduced by using the secret is pretty minimal, and I think that the steps necessary to change this behavior will have significant negative consequences to the user and will introduce a small chance of a catastrophic database loss. It's my assessment that most users will prefer not to make that trade off, so at this point I'm going to leave it the way it is. That said, if you see anything wrong with my assessment I'll definitely reconsider.

    Ben

     
  • Guy

    Guy - 2015-01-13

    You make a very good point that HMAC challenges usually involve the secret being shared. As such, it's not fair to assume that the HMAC challenge/response slot can be used across multiple applications without risk (although some applications including the Yubico PAM module don't require the shared secret to be disclosed).

    I agree with your summary that it comes down to the minimal security risk vs the inconvenience (especially for NFC). I respect your judgement call (even if I don't necessarily agree with it!)

    Many thanks for taking the time to read and answer my questions.

    Cheers
    Guy

     

    Last edit: Guy 2015-01-13
  • Ben

    Ben - 2015-01-13

    I just dug into the source for the PAM module since I was curious to see if yubico had thought of a solution to the problems I mentioned. They're doing exactly what I had outlined above (ie sending two challenges each time). Since it sounds like you're using this functionality, I'm curious: do you have to press the button twice per login? That's the behavior I'm expecting, but I'm wondering if there's a way around it. Thanks a ton for your input, it really helps me to understand the different ways that keechallenge is getting used.

    Ben

     
  • Guy

    Guy - 2015-01-13

    I'm not actually using the PAM module; I also looked through the code! Like you, I'd assume it would need two button presses (if YubiKey programmed to require a button press). I can only assume that most people configure their key to not require this.

    The difference with KeeChallenge is when it's used on an android phone - as you say this would need two "taps".

    I also stumbled on the full disk encryption "implementation guide" document linked from https://www.yubico.com/applications/disk-encryption/full-disk-encryption/ where YubiCo document both approaches.

    Cheers
    Guy

     
  • SSL

    SSL - 2015-10-22

    Hi,

    Can you have a look on some files in attachment (svg images) ?
    I have tried to well understand how KeeChallenge work using some kind of uml diagram.

    In my view, there should be no need of storing the Yubico HMAC Secret Key in the XML (even if it is crypted).

    Can you comment plz ?


    EDIT : Additionnal explanation

    1- When you open the kdbx, you need to run a CR (challenge response) to uncrypt the password.
    At this point, you don't know the HMAC to perform a complete CR as it is crypted in the XML.
    In order to get a R (response) to be use for uncrypt the password stored in the XML, you perform a partial CR which will give you a R (not certified by the full CR process)
    => I guess the user will have to push the button (1st time).
    Now you have a R corresponding to a C (stored in the XML).
    You use the R to uncrypt the requierd password for uncrypting the kdbx.
    Two case :
    A) the CR is not comming from the right Yubico Key, the R will not permit to uncrypt the pw so you will not be able to the open kdbx file.
    B) the CR is comming from the right Yubico key, then you get access to the pw and to the kdbx content.

    2- On previous posts ahead, you said using the HMAC Secret to crypt the database. So why use this specific secret key ? You could use the partial CR as in point 1-. Even if you are using a two step cyphering (xml and kdbx). There is no need to use the HMAC. no ? as your first CR pair is defacto validating the Yubico key ?

    3- made some changes in the database (or not), and close it

    4- You make a new CR in order to get a new R which will be use to Re encrypt the password using a new CR pair. Why using HMAC ? as if files have been stolen (or lost if they were on a usb key), there is no need to change every time as the hacker will have a snapshot to work with. More over, this snapshot could be cracked to get the HMAC Secret, and then hack easily the kdbx. As I said ahead, your first CR pair is defacto validating the Yubico key.

    In my view, you need the HMAC only when initializing the first CR. You should ask the user to write down the Challenge key as it will be its recovery key. Then, when cyphering the db, you make a second CR to encrypt in the XML the first Response (which will be use to crypt/uncrypt the kdbx file).

    BR,
    Avitus

     

    Last edit: SSL 2015-10-23
    • Ben

      Ben - 2016-05-10

      Avitus,

      Sorry for taking so long on this! I have had some personal things going on that have limited my available bandwidth for maintaining this project. To answer your question, challenge-response requires a shared secret to operate. In brief, I first generate a random string of bits to serve as the challenge. Then, I use my copy of the secret to generate the correct response. The yubikey does the same thing using its copy of the secret, and sends its response back. I then compare that response to my "correct" response. If the two match, I consider the authentication successful. As you can see, the underlying algorithm requires that we store a copy of the secret somewhere. Since we're already doing that, there's no real reason not to use the secret as the encryption key. I hope that this helps,

      Ben

       
  • vhaiym

    vhaiym - 2017-08-11

    deleted

     

    Last edit: vhaiym 2017-08-12

Log in to post a comment.

MongoDB Logo MongoDB