Skip to content

Using two yubikeys not covered under guide #19

Description

@wsargent

So, this might require more feedback, as am currently flummoxed.

If you want to use a Yubikey for Windows / MacOS / Linux login as part of a multi-factor authentication, then Yubico advises having a second Yubikey as backup. This works fine, since I can use a Yubikey Nano for the Macbook Pro, and leave the desktop one plugged in.

However, if you try copying the GPG secret key and subkeys onto a second Yubikey, "keytocard" will not let you. You'll get "secret key already stored on a card" and other similar warnings. Is it not a good idea to use two Yubikeys?

Activity

  1. wsargent commented on Sep 22, 2016

    @wsargent
    ContributorAuthor

    It seems like the best practice is "one GPG key per device". I don't know if they're allowed to be cross signed, but I presume so.

  2. wsargent commented on Sep 23, 2016

    @wsargent
    ContributorAuthor

    Okay, I think this is slightly more complicated. There needs to be a single KEYID, but then there need to be different subkeys for each token. Then, if a token gets stolen, you can revoke the subkey and keep the root key safe.

    So this means it's not sufficient to generate a revocation certificate for the root, as is done in

    https://github.com/drduh/YubiKey-Guide#create-revocation-certificate

    There ALSO needs to be a revocation certificate for each subkey set tied to each token.

  3. wsargent commented on Sep 24, 2016

    @wsargent
    ContributorAuthor

    Except... apparently having two encryption subkeys is a good way to get GPG very, very confused. Oh dear.

  4. wsargent commented on Sep 24, 2016

    @wsargent
    ContributorAuthor
  5. wsargent commented on Sep 24, 2016

    @wsargent
    ContributorAuthor

    One might be tempted to have one subkey per machine so that you only need to exchange the potentially compromised subkey of that machine. In case of a single subkey used on all machines, it needs to be exchanged on all machines in case of a compromising.

    But this only works for signing subkeys. If you have multiple encryption subkeys, gpg is said to encrypt only for the most recent encryption subkey and not for all known and not revoked encryption subkeys.

    https://wiki.debian.org/Subkeys

  6. wsargent commented on Sep 24, 2016

    @wsargent
    ContributorAuthor

    After you purposely delete the secret key stubs from your keyring (otherwise it will say the keys are already associated with another card), you can even put these same keys on a different smartcard by repeating part of the process above.

    https://gist.github.com/ageis/5b095b50b9ae6b0aa9bf

  7. wsargent commented on Sep 24, 2016

    @wsargent
    ContributorAuthor
  8. wsargent commented on Sep 24, 2016

    @wsargent
    ContributorAuthor
  9. wsargent commented on Sep 26, 2016

    @wsargent
    ContributorAuthor

    Consider purchasing a pair and programming both in case of loss or damage to one of them.

    https://github.com/drduh/YubiKey-Guide#purchase-yubikey

  10. wsargent commented on Sep 26, 2016

    @wsargent
    ContributorAuthor
    Please select where to store the key:
       (1) Signature key
       (3) Authentication key
    Your selection? 3
    
    gpg: WARNING: such a key has already been stored on the card!
    
    Replace existing key? (y/N) y
    
    gpg: secret key is already stored on a card
    

    https://lists.gnupg.org/pipermail/gnupg-users/2010-October/039592.html

    So the way I've worked around this is to just delete the entire .gnupg directory and reimport from master for each key, but this seems suboptimal.

  11. wsargent commented on Sep 26, 2016

    @wsargent
    ContributorAuthor

    I assume, although keytocard is documented as moving the key to the card, it actually copies it.

    It copies, but if you then save the changes to your local disk, the original copy on local disk is deleted - so calling it a "move" operation is correct. If you want to keep a backup copy on local disk, you need to quit without saving immediately after running 'keytocard'. This behaviour is a well-known gotcha.

    http://www.gossamer-threads.com/lists/gnupg/users/76764#76764

  12. wsargent commented on Sep 26, 2016

    @wsargent
    ContributorAuthor

    But because I've already sharded my key with a previous NEO (still in my possession, no need to generate new keys), I get this response when executing the gpg> keytocard command:

    gpg: secret key already stored on a card.

    So now what? Do I delete the secring.gpg file on my hard drive and re-import the keys? Do I do that every time I configure a new NEO with my PGP keys?

    In short, you don't need to delete whole keyring, just the key that is marked as exported to smartcard (Neo). You first need to delete the secret key from keyring with gpg --delete-secret-key. Then you import the full key (how it was before you moved it to smartcard).

    Then you use the classic keytocard, etc.

    http://forum.yubico.com/viewtopic.php?f=26&t=2095

  13. added a commit that references this issue on Nov 8, 2017
    36ce5e8
  14. added a commit that references this issue on Dec 2, 2017
    a5fd067
  15. 59 remaining items

  16. iandstanley commented on Sep 29, 2021

    @iandstanley
    Contributor

    @Neopallium your process seems needlessly risky, at least for anyone using gpg for anything besides two dedicated YubiKeys. A similar result can be achieved using the --homedir parameter (the following assumes the YubiKeys have not been initialized, but the private soft key has been created):

    
    cp -a ~/.gnupg ~/.gnupg_KEY1
    
    cp -a ~/.gnupg ~/.gnupg_KEY2
    
    gpg --homedir ~/.gnupg_KEY1/ --card-status  # initialize first YubiKey
    
    gpg --homedir ~/.gnupg_KEY1/ --edit-key $KEYID
    
    # complete the 'keytocard' process, then swap YubiKeys
    
    gpgconf --kill gpg-agent  # alternative to 'pkill gpg-agent'
    
    gpg --homedir ~/.gnupg_KEY2/ --card-status  # initialize second YubiKey
    
    gpg --homedir ~/.gnupg_KEY2/ --edit-key $KEYID
    
    # complete the 'keytocard' process
    
    

    After that, the private soft key can be removed from each new homrdir (along with any other private or public keys that are not needed) and shell aliases (or a script) can be used to select the correct homedir at time of use. A script could even call ykman info to get the serial number of the connected YubiKey and use that to determine which homedir to use.

    For creating the duplicate key all you need to do is quit rather than save after issuing keytocard.

    In use switching Yubikeys is easy ...

    Switching GPG fits like this means that you would have to maintain two independent GPG key rings

    It is much easier to insert the other Yubikey and run

    gpg-connect-agent "scd serialno" "learn --force" /bye

    I have a script in the rep to save you having to remember the command

  17. bradical commented on Sep 30, 2021

    @bradical

    Thanks @iandstanley

    With ssh keys revoking would require you to remove the key’s is from every server where it is used.

    For each server you would have to create an entry for the replacement key. This is better done upfront rather than while your mind is worrying about stolen/lost keys.

    It is better to have a different ssh key on each Yubikey. And copy both public keys to each server you log into. Revoking the exposed key would still involve deleting a line from each server but this is less work than adding a new key and removing the old key whilst under stress.

    Good point. I'll stick to having multiple SSH keys.

    Different ssh keys just need a ssh config tweak (comment out or change) ... but you can setup both in advance with separate hosts clauses eg hostname-k1 and hostname-k2 clauses)

    Can you clarify what you mean here? I'm currently using these two guides to generate an SSH key on my yubikey. Are you saying there is a way to easily switch between them as a default? I'm aware of using -i or something to point to a specific key. But wasn't sure if you meant something else.

    PS don’t forget the new Yubikey blue security keys now support resident ssh keys (as well as Yubikey 5, 4 and neo keys)

    I'm using a 5c and 5ci. Are you saying they support something other than what I mentioned above from the Github key:

    ssh-keygen -t ecdsa-sk -f ~/.ssh/id_ecdsa_sk
    

    Yes

    See section on multiple keys to import a key into different keys

    Section of what? The documentation or this thread? The one thing I've been confused about is when exactly to swap cards and CTRL-C to quit without saving. I was doing:

    • generate a PGP key
    • insert card
    • edit-key
    • keytocard process to add to 1
    • ctrl-C to quit without saving
    • swap cards
    • edit-key
    • keytocard on the other yubikey
    • save this time to allow it to remove local credentials

    Is that the correct sequence to get it loaded on both?

    It is much easier to insert the other Yubikey and run

    gpg-connect-agent "scd serialno" "learn --force" /bye

    I have a script in the rep to save you having to remember the command

    Going to try this to swap what's attached to the machine's local keys.

  18. iandstanley commented on Sep 30, 2021

    @iandstanley
    Contributor
  19. bradical commented on Sep 30, 2021

    @bradical

    Can’t remember if I mentioned you can use GPG keys for ssh keys using the GPG agent rather than the ssh agent

    intriguing! any docs to share on this? I'd be interested in having few keys to manage.

  20. kurtmckee commented on Jun 1, 2022

    @kurtmckee
    Contributor

    I found that gpg always ignored the signing key ID specified in my git config, and instead always asked for the most-recently written Yubikey.

    StackOverflow had this solution:

    To use a specific subkey, KEYID must be appended with !. So the configuration should look like the following:

    [user]
        name = Andrzej Ośmiałowski
        email = me@osmialowski.net
        signingKey = KEYID!

    I can now plug in either of my Yubikeys, each with a distinct signing subkey, and configure git using git config --global user.signingkey KEYID!.

    With this in place, it looks like there's no need to duplicate the same signing key to each Yubikey, and no need to run that learn --force command.

  21. bradical commented on Jun 1, 2022

    @bradical

    So the idea here is that you need to manually update your git config to switch between the keys? Or is there a more seamless less manual process for it?

  22. kurtmckee commented on Jun 1, 2022

    @kurtmckee
    Contributor

    You're right, it's a manual process. I couldn't find a way to make gpg select a signing subkey based on whichever Yubikey is plugged in, but since I struggled to configure which key was used at all, I wanted to note the requirement to add an exclamation point.

  23. smlx commented on Jun 2, 2022

    @smlx
    Contributor

    I couldn't find a way to make gpg select a signing subkey based on whichever Yubikey is plugged in

    This is a function of the gpg-agent, it should not return a signing key as being "available" unless the key is plugged in. Might be a bug in gpg-agent?

  24. kurtmckee commented on Jun 2, 2022

    @kurtmckee
    Contributor

    gpg-agent...should not return a signing key as being "available" unless the key is plugged in

    Indeed, it would not claim a signing key was available until the correct key was plugged in. This was my setup:

    • Yubikey 1, with signing subkey 1
    • Yubikey 2, with signing subkey 2

    I configured git to use subkey 1 on Yubikey 1. However, gpg ignored that configuration and always asked me to plug in Yubikey 2 with subkey 2. I confirmed the command line that git was running (C:\path\to\gpg.exe -bsau ${KEYID1}) but that wasn't sufficient to make gpg actually use that key ID.

    Adding the exclamation mark was what finally got gpg to respect the requested key ID (the command line was C:\path\to\gpg.exe -bsau ${KEYID1}!), and find it on my primary Yubikey that was already plugged in.

    Until I added an exclamation mark to the end of the key ID in my git config, gpg utterly ignored my configuration and always asked for the wrong subkey.

    It would be nice if I could configure git (and subsequently gpg) to use the subkey on whichever Yubikey is already plugged in. Unfortunately, everything I've tried results in gpg demanding I plug in Yubikey 2 with signing subkey 2, so I'm noting here that the exclamation mark is necessary.

  25. smlx commented on Jun 2, 2022

    @smlx
    Contributor

    Right, but that is the bug. gpg-agent should recognise that the other subkey is available right now and just use that instead.

    Do you see the same problem if you specify the master KEYID in git config?

  26. kurtmckee commented on Jun 2, 2022

    @kurtmckee
    Contributor

    If I specify the master KEYID (I've only imported the public key and given it ultimate trust; the private key is locked away), then gpg on Linux doesn't prompt me for either Yubikey but instead exits with the message error: gpg failed to sign the data, and then git reports fatal: failed to write commit object.

    The only solution I've found is to specify the signing subkey ID explicitly, and it has to have a trailing exclamation mark for gpg to respect the configuration.

    To be clear: I'm not requesting support. I'm noting how I overcame an issue that seems similar to what @jsatk reported, above. It's been three years since that comment, so I wanted to note how I solved it.

  27. iandstanley commented on Jun 2, 2022

    @iandstanley
    Contributor
  28. kurtmckee commented on Jun 2, 2022

    @kurtmckee
    Contributor

    Thanks @iandstanley! I'm aware of the gpg-connect-agent "scd serialno" "learn --force" /bye command, but since each of my Yubikeys has a unique signing subkey I don't think this solution is applicable. I did try running that command while troubleshooting but it had no effect that I could see.

  29. smlx commented on Jun 3, 2022

    @smlx
    Contributor

    https://www.gnupg.org/documentation/manuals/gnupg/Agent-HAVEKEY.html

    This command is what gpg uses to interrogate the gpg-agent for available signing keys before attempting to use them for a signing operation. I think the agent must be returning keys as available even when they are not, which is why I suggested this was a bug in the agent that should be reported upstream.

  30. kurtmckee commented on Jun 3, 2022

    @kurtmckee
    Contributor

    Ah! I see. Here's the output I'm seeing with Yubikey 1 and signing subkey 1 plugged in -- AND with it unplugged (it's the same output whether the Yubikey is plugged in or not):

    C:\> gpg-connect-agent.exe "HAVEKEY 1061D8DD34BD86E7C7890B9D64713C0B5BA8E1C2" /bye
    ERR 67108881 No secret key <GPG Agent>
    

    At this point, this has turned into more of a forum thread instead of a GitHub issue so I'm going to stop posting. I have a manual fix for integrating git with gpg with two Yubikeys with unique signing subkeys, and I've posted it here for others since this issue is a top search result.

    Thank you all for your support and suggestions, and to drduh for a tremendously helpful guide!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions