Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Using two yubikeys not covered under guide #19

Closed
wsargent opened this issue Sep 21, 2016 · 86 comments
Closed

Using two yubikeys not covered under guide #19

wsargent opened this issue Sep 21, 2016 · 86 comments

Comments

@wsargent
Copy link
Contributor

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?

@wsargent
Copy link
Contributor Author

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.

@wsargent
Copy link
Contributor Author

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.

@wsargent
Copy link
Contributor Author

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

@wsargent
Copy link
Contributor Author

@wsargent
Copy link
Contributor Author

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

@wsargent
Copy link
Contributor Author

@wsargent
Copy link
Contributor Author

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

@wsargent
Copy link
Contributor Author

@wsargent
Copy link
Contributor Author

This seems to assume THREE smartcards...

https://github.com/flamsmark/documentation/blob/master/gpg/smartcard-keygen.md

@wsargent
Copy link
Contributor Author

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

@wsargent
Copy link
Contributor Author

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.

@wsargent
Copy link
Contributor Author

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

@wsargent
Copy link
Contributor Author

wsargent commented Sep 26, 2016

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

EliasGabrielsson added a commit to EliasGabrielsson/YubiKey-Guide that referenced this issue Nov 8, 2017
* Adding part descriping how to use multiple Yubikey with same keyset.
* Changed from `ykpers` to `ykman` as it is more feature complete.
* Added `pinentry-mac` which is preferable as it works with GUI.
EliasGabrielsson added a commit to EliasGabrielsson/YubiKey-Guide that referenced this issue Dec 2, 2017
* Adding part descriping how to use multiple Yubikey with same keyset.
* Changed from `ykpers` to `ykman` as it is more feature complete.
* Added `pinentry-mac` which is preferable as it works with GUI.
@jwr
Copy link

jwr commented Jul 29, 2018

This isn't a big problem: the way I do it is delete the secret keys completely, re-import them from my secure storage, and produce the second YubiKey by just following the instructions.

@Ty-Stelow
Copy link

I keep trying this process but it always asks for the last Yubikey I sent the keys to.

@taigrr
Copy link
Contributor

taigrr commented Sep 8, 2018

I routinely swap between two YubiKeys, the Nano in my docking station and the Neo on my keychain.

I have the same encryption and authentication keys on both YubiKeys and distinct signing keys on each.

In order to swap between which YubiKey I want to use, I do the following:

  1. killall gpg-agent
  2. rm -r ~/.gnupg/private- keys-v1 .d/
  3. Plug in the new YubiKey
  4. gpg --card-edit
    (makes sure the card is visible, also notifies gpg which keys are available for current card)

Now the alternate card should be usable. If it's not, unplug the YubiKey and repeat steps 1-4 again, it should work the second time.

I've found the command gpg-connect-agent updatestartuptty /bye can also be helpful.

This process should help you when you are trying to create the YubiKeys as well.

@Ty-Stelow
Copy link

Thanks! I will give it a shot.

@demonbane
Copy link

If anyone is wanting to use @taigrr's approach above, be aware that this will delete all private keys you might have in your keychain. If you only have the one that's on your card, that's great, but if you have other private keys that are stored there, this will delete all of them.

If that's the case, you can just delete the individual stubs for your card by getting the keygrip for each of the subkeys on your card using gpg -K --with-keygrip, and then only deleting <yourkeygrip>.key for each subkey inside private-keys-v1.d. Or, in script form:

#!/usr/bin/env bash
keyid=YOUR_KEY_ID_GOES_HERE
gpgconf --kill gpg-agent
cd "$(gpgconf --list-dirs homedir)/private-keys-v1.d"
gpg -K --with-keygrip --with-colons "$keyid" | \
awk -F: '/^grp/ { print $10".key"; }' | \
xargs rm -vf

@staticvoidmaine
Copy link

staticvoidmaine commented Jan 2, 2019

I'm currently running into a problem with ssh authentication with multiple yubikeys. I have keytocard'ed the same encrypt, sign, and auth subkeys to 3 different yubikeys. I have also added each auth key to the ssh agent (gpg-driven of course).

The key here is that each ssh public key has a different cardno. To get started, I ssh'd into my raspberry pi via password and set all three keys in my authorized_keys file in hopes that it would just work for whichever key I had plugged in at the time.

Unfortunately, it's looking for the first public key I pasted into authorized_keys and wouldn't let me through until I connected the right key.

Does anyone have any tips or ideas on how to properly manage ssh identities so that all three keys are effectively "the same" for the purpose of being backups of eachother?

Should I be generating a different gpg key for each yubikey and just sharing all three public keys throughout my network of devices? Even if I did that, would that solve the problem of selecting the correct identity based on which yubikey is plugged in?

I'd love to hear any/all thoughts, opinions, or advice.

Thanks!

@moonmeister
Copy link

Yes, you should share a master key but creat unique sub keys to each yubikey.

@jsatk
Copy link

jsatk commented Jan 2, 2019

FWIW I'm using two YubiKeys. One is back up.

I created a two sets of three subkeys (one S, one E, one A) for each. 90% of the time when I need to use my yubikey (i.e. git commit) it prompts me for the one that's already plugged in and I enter my pin. Sometimes it, seemingly randomly, asks me for the other one. I click cancel and it fails. I try again and it goes to the one that's inserted.

I don't know how it chooses which subkeys to use. But it's been working fine for me.

@moonmeister
Copy link

I just only have the public key installed for the key I regularly use. I can always add the public key for my backup if needed.

@drduh
Copy link
Owner

drduh commented Jan 3, 2019

The key here is that each ssh public key has a different cardno.

This shouldn't be relevant to SSH - or are you literally using cardno:12345 as the user to SSH as? If so, don't do that and pick a single username which will have multiple public keys authorized.

I use many keys and these two commands let me switch between them with ease:

$ pkill gpg-agent ssh-agent pinentry ; eval $(gpg-agent --daemon --enable-ssh-support)
$ gpg-connect-agent updatestartuptty /bye

I don't know about this business removing ~/.gnupg/private-keys-v1 as they're not even used for SSH. Perhaps I've misunderstood the intention, but I routinely switch between keys (each with a unique identity and SC) and have no trouble encrypting, signing and authenticating with SSH. Each of these keys also has a duplicate backup which I swap for every several weeks without fail.

@jsatk
Copy link

jsatk commented Jan 3, 2019

Thanks @drduh.

Would you open to adding or accepting a pull request detailing how to support two-or-more YubiKeys?

@drduh
Copy link
Owner

drduh commented Jan 3, 2019

Yes, of course - PRs are welcome!

@staticvoidmaine
Copy link

staticvoidmaine commented Jan 3, 2019

@drduh

This shouldn't be relevant to SSH - or are you literally using cardno:12345 as the user to SSH as? If so, don't do that and pick a single username which will have multiple public keys authorized.

You're totally right - I didn't realize that the tail end of a key in the authorized_keys file is just a comment (for an embarrassingly long time) . What I was referring to is the fact that I copied the same key over to the authorized_keys file 3 times (thinking the comment at the end mattered and made the key unique) and made the mistake of thinking that was causing the gtk dialog that popped up asking to "please insert cardno xxxxxxx and try again" upon attempting to ssh into the raspi.

I use many keys and these two commands let me switch between them with ease:

$ pkill gpg-agent ssh-agent pinentry ; eval $(gpg-agent --daemon --enable-ssh-support)
$ gpg-connect-agent updatestartuptty /bye

Can you explain what the above commands do and why they are responsible for allowing you to use multiple keys? I'm new to yubikeys/pgp/gpg and have a goal that I'm not sure is correct: to have a shared master key and to have redundant yubikeys with the same subkeys on them for interchangeability. I have accomplished the keytocard end of this, technically speaking.

Are the stubs potentially the source of my problems? Are the stubs pointing to a specific cardno? I left one set of stubs thinking that all gpg-agent would need is to know that the keys reside on a smart card in general, not considering whether or not it pointed to a specific smartcard/key

I don't know about this business removing ~/.gnupg/private-keys-v1 as they're not even used for SSH. Perhaps I've misunderstood the intention, but I routinely switch between keys (each with a unique identity and SC) and have no trouble encrypting, signing and authenticating with SSH. Each of these keys also has a duplicate backup which I swap for every several weeks without fail.

What is involved in making unique keys work? I feel like I'm misunderstanding something because I'm reading about your setup and thinking that something you encrypt with key A will not be able to be decrypted by key B. Is that correct?

I want key A, B, and C to be able to all encrypt/decrypt data interchangeably. Maybe this goal doesn't make sense?

Would you be willing to take a look at these questions and help point me in the right direction to achieve my goal, or maybe redirect me to a better strategy with some context as to why?

Thank you in advance!

@staticvoidmaine
Copy link

staticvoidmaine commented Jan 4, 2019

I think this part of your guide solves my problem:

https://github.com/drduh/YubiKey-Guide#optional-save-public-key-for-identity-file-configuration

Killer job with the guide btw. Yubikeys would have been totally inaccessible to me without it. Cheers.

@drduh
Copy link
Owner

drduh commented Jan 7, 2019

Thanks! I'll describe the use of multiple keys, multiple identities and the recovery/revocation process I use soon. The documentation for this is incomplete at the moment.

@iandstanley
Copy link
Contributor

I use two Yubikeys for my GPG needs.

  1. Create Yubikey1 with the normal keytocard procedure
  2. Quit GPG but REMEMBER TO NOT SAVE
  3. Insert Yubikey2 and repeat the procedure
  4. Quit and SAVE

This will leave you with two Yubikeys with identical subkeys.

However, GPG will have deleted the actual keys in step 4 above and replaced them with key stubs pointing to Yubikey2

To use Yubikey1 you need to force GPG to repoint the stubs to the new card...

Fortunately, I have a script to do that see here

`
#!/bin/sh

To make a duplicate Yubikey for GPG keys

1. Insert Yubikey1

2. Create keys/subkeys

3. Run keytocard to transfer keys to Yubikey1

4. QUIT WITHOUT SAVING!!!!!

This will leave the keys on the Yubikey but NOT change the

GPG keyring to point to the Yubikey1 with a stub

5. Insert Yubikey2

6. Run keytocard to transfer keys to Yubikey2

7. QUIT and SAVE to make GPG point it's stubs to Yubikey2

Running any decrypt, auth or sign will now ask you to insert Yubikey2

To switch to Yubikey1 at any time run this script to force GPG

to repoint the key stubs to the inserted Yubikey

read -p "Insert the Yubikey you want to use .... " ignore
echo "Switching GPG to backup Yubikey ..."

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

You can use this script to switch back and forth between the two Yubikeys.

@jwr
Copy link

jwr commented May 5, 2021

This might not fit everyone's use case, but I eventually realized that I mostly use my YubiKeys for authentication (SSH and FIDO2/Webauthn) and encrypting/decrypting data (such as backups). Which means that they don't need to be identical. So I generated two sets of keys and have two distinct YubiKeys storing them. My data is simply encrypted for two recipients, and I add two SSH or FIDO/Webauthn keys to all systems.

Just wanted to put it out there, because for many people this might be enough, and this approach requires zero fiddling with GPG and stubs.

@varavvai
Copy link

varavvai commented May 5, 2021

It won't help if you are using yubikey 2FA.
The task is to create two absolutely identical sets of keys.

@iandstanley
Copy link
Contributor

iandstanley commented May 16, 2021 via email

@Neopallium
Copy link

I just setup two Yubikeys with the same gpg keys:

  1. Backup gpg files: cp -a ~/.gnupg ~/.gnupg.bak
  2. Do normal keytocard process for first Yubikey (KEY1).
  3. Stop gpg-agent, maybe not required: pkill gpg-agent
  4. Save gpg files for first Yubikey: mv ~/.gnupg ~/.gnupg_KEY1
  5. Restore backup: cp -a ~/.gnupg.bak ~/.gnupg
  6. Do normal keytocard process for second Yubikey (KEY2).
  7. Stop gpg-agent, maybe not required: pkill gpg-agent
  8. Save gpg files for second Yubikey: mv ~/.gnupg ~/.gnupg_KEY2
  9. Switch back to first Yubikey: ln -s ~/.gnupg_KEY1 ~/.gnupg
  10. Move ~/.gnupg.bak to some safe place offline.

I use this script to switch gpg between Yubikeys:

#!/bin/bash
#

KEY_NAME="KEY1"

if [[ "$1" == "KEY2" ]]; then
	KEY_NAME="KEY2"
fi

echo "switch to key: $KEY_NAME"

# make sure gpg-agent is stopped.  Maybe there is a better way.
pkill gpg-agent
sleep 1
pkill -9 gpg-agent

cd $HOME

rm -f .gnupg
ln -s .gnupg_${KEY_NAME} .gnupg

@Whompithian
Copy link

@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.

@Neopallium
Copy link

gpgconf --kill gpg-agent # alternative to 'pkill gpg-agent'

Thanks for that command.

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.

I prefer to switch .gnupg using symlinks so that the change effects all open shells/programs. I use tmux a lot and want the change to apply to everything.

Good idea to grab the serial number.

@Whompithian
Copy link

I prefer to switch .gnupg using symlinks so that the change effects all open shells/programs. I use tmux a lot and want the change to apply to everything.

An alternative to the homedir parameter is the GNUPGHOME environment variable.

@bradical
Copy link

Is there a definitive solution to this? I think I just ran across the same thing and while I'm able to get the same keys added to two yubikeys, only one of them seems to be recognized as being linked to from gpg:

sec>  rsa4096/D6B9198489FD17F3 2021-09-29 [SC]
      B38EEAFAAAE9B1327162CA2ED6B9198489FD17F3
      Card serial no. = ...

Therefore, whenever I try to use the other for signing, it prompts for the other card.

To clarify, is it actually possible for that subkey to point to more than one card at a time interchangeable? or do you have to use one as the primary and then do something to forcibly update that reference?

I have a similar question for SSH keys.

@holderl5
Copy link

It would require tagging a single key with multiple cards, which I do not know if gnupg supports - or if it is even on their radar. The command I (re) posted above to switch works with minimal frustration until they do get such a feature.

@bradical
Copy link

Thanks @holderl5. Believe you're referring to this comment: #19 (comment).

Does anyone know if such a thing is possible with SSH

@iandstanley
Copy link
Contributor

It would require tagging a single key with multiple cards, which I do not know if gnupg supports - or if it is even on their radar. The command I (re) posted above to switch works with minimal frustration until they do get such a feature.

It does and it doesn't

Technically having a key on a Yubikey results in having a pointer to the Yubikey serial no in your key ring.

So when GPG is asked to use that key it looks up in your key ring and finds it doesn't have the key but a stub pointing to a Yubikey with a specific key ring.

Assuming the operating system has smart card software installed (see the guide) the GPG makes a call to the smart card software supplying the Yubikey serial num.

The smart card daemon then prompts the user for a specific Yubikey (the one with the specific serial no in the stub).

HOWEVER ...

If you follow the instructions in this guide you can place the same key on any number of Yubikeys

Each time you copy the key to the card the stub will be recreated to point to that Yubikey.

If you last installed the GPG key on card B then your key ring Stub points to Yubikey B. If you place your Yubikey A into the USB port you need to force GPG to rescan the USB ports and recreate the stub to point at Yubikey A. This can be done by issuing the command :

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

Then the GPG key ring stub points to Yubikey A

I have added a script into the repository so you don't need to remember the long command line

@iandstanley
Copy link
Contributor

Thanks @holderl5. Believe you're referring to this comment: #19 (comment).

Does anyone know if such a thing is possible with SSH

First an ssh key is a different storage format (even when they use the same encryption for the key)

You can create a x509 key using OpenSSL, export the auth key and then import that into the Yubikey

This process is a little messy and it is easier to just create a different ssh key on the Yubikey and tweak your ssh config on your client (just ssh-keygen using a “-sk” suffixed key type.

But there is a different issue here

With GPG keys lost duplicates are a lot less work to revoke of compromised as they can be revoked but just applying a revocation certificate and pushing to a public server.

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.

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)
A

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

@iandstanley
Copy link
Contributor

Is there a definitive solution to this? I think I just ran across the same thing and while I'm able to get the same keys added to two yubikeys, only one of them seems to be recognized as being linked to from gpg:


sec>  rsa4096/D6B9198489FD17F3 2021-09-29 [SC]

      B38EEAFAAAE9B1327162CA2ED6B9198489FD17F3

      Card serial no. = ...

Therefore, whenever I try to use the other for signing, it prompts for the other card.

To clarify, is it actually possible for that subkey to point to more than one card at a time interchangeable? or do you have to use one as the primary and then do something to forcibly update that reference?

I have a similar question for SSH keys.

Yes

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

Basically you can only use one at a time on a single machine but you can issue a command to switch keys (see my script in the repo)

@iandstanley
Copy link
Contributor

iandstanley commented Sep 29, 2021

@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

@bradical
Copy link

bradical commented Sep 30, 2021

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.

@iandstanley
Copy link
Contributor

iandstanley commented Sep 30, 2021 via email

@bradical
Copy link

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.

@kurtmckee
Copy link

kurtmckee commented Jun 1, 2022

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.

@bradical
Copy link

bradical commented Jun 1, 2022

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?

@kurtmckee
Copy link

kurtmckee commented Jun 1, 2022

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.

@smlx
Copy link
Contributor

smlx commented Jun 2, 2022

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?

@kurtmckee
Copy link

kurtmckee commented Jun 2, 2022

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.

@smlx
Copy link
Contributor

smlx commented Jun 2, 2022

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?

@kurtmckee
Copy link

kurtmckee commented Jun 2, 2022

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.

@iandstanley
Copy link
Contributor

iandstanley commented Jun 2, 2022 via email

@kurtmckee
Copy link

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.

@smlx
Copy link
Contributor

smlx commented Jun 3, 2022

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.

@kurtmckee
Copy link

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
Labels
None yet
Projects
None yet
Development

No branches or pull requests