drduh / YubiKey-Guide

Guide to using YubiKey for GnuPG and SSH
http://drduh.github.io/YubiKey-Guide/
MIT License
11.15k stars 1.19k forks source link

gpg: decryption failed: No secret key #328

Closed lattice0 closed 1 year ago

lattice0 commented 2 years ago

After importing my key to another PC:

ss@pc:~$ echo "test message string" | gpg --encrypt --armor --recipient 1234567890 -o encrypted.txt
gpg: BBBBBBBBBBBBBBBB: There is no assurance this key belongs to the named user

sub  cv25519/AAAAAAAAAAAAAA 2018-11-30 proton@srp.modulus
 Primary key fingerprint: AAAA AAAA AAAA AAAA AAAA  AAAA AAAA AAAA AAAA AAAA
      Subkey fingerprint: AAAA AAAA AAAA AAAA AAAA  AAAA AAAA AAAA AAAA AAAA

It is NOT certain that the key belongs to the person named
in the user ID.  If you *really* know what you are doing,
you may answer the next question with yes.

Use this key anyway? (y/N) y
ss@pc:~$ gpg --decrypt --armor encrypted.txt
gpg: encrypted with 255-bit ECDH key, ID CCCCCCCCCCCCC, created 2018-11-30
      "something@srp.modulus"
gpg: decryption failed: No secret key

I have no idea what is going on.

ss@pc:~$ gpg --card-status
Reader ...........: 1050:0407:X:0
Application ID ...: 12345678901234567890
Application type .: OpenPGP
Version ..........: 3.4
Manufacturer .....: Yubico
Serial number ....: 16358784
Name of cardholder: [not set]
Language prefs ...: [not set]
Salutation .......: 
URL of public key : [not set]
Login data .......: [not set]
Signature PIN ....: not forced
Key attributes ...: rsa4096 rsa4096 rsa4096
Max. PIN lengths .: 127 127 127
PIN retry counter : 3 0 3
Signature counter : 6
KDF setting ......: off
Signature key ....: AAAA AAAA AAAA AAAA AAAA  AAAA AAAA AAAA AAAA AAAA
      created ....: 2022-04-13 22:00:57
Encryption key....: BBBB BBBB BBBB BBBB BBBB  BBBB BBBB BBBB BBBB BBBB
      created ....: 2022-04-13 22:01:32
Authentication key: CCCC CCCC CCCC CCCC CCCC  CCCC CCCC CCCC CCCC CCCC
      created ....: 2022-04-13 22:01:59
General key info..: [none]
ss@pc:~$ gpg --list-secret-keys
ss@pc:~$ gpg --list-keys
/home/lz/.gnupg/pubring.kbx
---------------------------
pub   ed25519 2018-11-30 [SC]
      AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
uid           [ unknown] something@srp.modulus
sub   cv25519 2018-11-30 [E]

PS: ssh with public key works

smlx commented 2 years ago
gpg --encrypt --armor --recipient 1234567890
...
gpg: decryption failed: No secret key

This indicates that you don't have the secret key of 1234567890 in your gpg keyring. You can check via gpg -K.

lattice0 commented 2 years ago

@smlx gpg -K return empty. How can I SSH then, if no secret key? Maybe 1234567890 is the encryption one?

By the way, what I actually want to do is sign commits, for which I get the same error as above. The only thing that works in SSH.

What should I do?

Paraphraser commented 2 years ago

I don't know if this will help but these are the notes I made of the steps to follow on a new Linux system:

  1. Login.

  2. Add these lines to .profile (making sure to replace «your keyID here» with your keyID):

    export KEYID=«your keyID here»
    export GPG_TTY=$(tty)
    echo "KEYID=$KEYID, GPG_TTY=$GPG_TTY"
  3. Either source .profile or logout/login again so those variables get set.

  4. Initialise GnuPG:

    $ gpg -k
  5. Import your public keys.

    • if stored on a key server, something like:

      $ gpg --keyserver hkps://keyserver.ubuntu.com:443 --recv $KEYID
    • if you need to retrieve from another machine then:

      1. On that other machine:

        $ gpg --armor --output $KEYID.public.keys.asc --export $KEYID
      2. Transport the file to the new machine by some means, then import it:

        $ gpg --armor --import $KEYID.public.keys.asc
  6. Check what got imported:

    $ gpg -k $KEYID

    You should get something other than silence or an error.

  7. Edit to set ultimate trust:

    $ gpg --edit-key $KEYID
    trust
    5
    y
    quit
  8. Confirm no private keys in place:

    $ gpg -K $KEYID
    gpg: error reading key: No secret key
  9. Insert the YubiKey.

  10. Run:

    $ gpg --card-status

    You'll get a whole lot of output about the card and keys stored on it. The result is the stubs pointing to your private keys stored on the YubiKey being added to ~/.gnupg/private-keys-v1.d.

  11. Repeat the private keys check:

    $ gpg -K $KEYID

    This should produce a result, including these critical bits:

    ssb>  rsa4096 yyyy-mm-dd [A]
    ssb>  rsa4096 yyyy-mm-dd [E]
    ssb>  rsa4096 yyyy-mm-dd [S]
  12. Remove the YubiKey.

  13. Create a test file:

    $ ls -al >plaintext.txt
  14. Encrypt that file:

    $ gpg --armor --recipient $KEYID --output ciphertext.asc --encrypt plaintext.txt
  15. Try to decrypt that file:

    $ gpg --armor --output recovered.txt --decrypt ciphertext.asc

    The system will prompt:

    • To connect the card.
    • To unlock the card with the PIN.

    The YubiKey will flash waiting for a touch.

  16. Compare original with round-trip result

    $ diff -s plaintext.txt recovered.txt 
    Files plaintext.txt and recovered.txt are identical
lattice0 commented 2 years ago

@Paraphraser what if I only have the public key, not the key id?

Anyways

gpg --list-keys
/home/ss/.gnupg/pubring.kbx
---------------------------
pub   ed25519 2018-11-30 [SC]
      123456789ABCDEF123456789ABCDEF12345
uid           [ unknown] something@srp.modulus
sub   cv25519 2018-11-30 [E]

so I guess I have the key id. But I already did all of this process :( and SSH works

lattice0 commented 2 years ago
ss@pc:~$ gpg --edit-key CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
gpg (GnuPG) 2.2.27; Copyright (C) 2021 Free Software Foundation, Inc.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

pub  ed25519/AAAAAAAAAAAAAA
     created: 2018-11-30  expires: never       usage: SC  
     trust: unknown       validity: unknown
sub  cv25519/BBBBBBBBBBBBBB
     created: 2018-11-30  expires: never       usage: E   
[ unknown] (1). something@srp.modulus

there's just the E key. Is this wrong?

Paraphraser commented 2 years ago

In my earlier reply, I hope I didn't give you the impression I was any kind of expert on this stuff. I'm not (0.5 on a 10-point scale if I'm feeling generous). My general approach is to keep belting the problem with whatever digital hammer is within reach and only stop thwacking stuff when the thing I'm trying to achieve seems to work.

I won't say I followed the DrDuh guide exactly when I set up my own YubiKeys in late 2019 but the notes I made at the time show my process was reasonably close to what the guide says now.

Here are the patterns I see on my own systems:

$ gpg -k $KEYID 
pub   rsa4096/0xAAAAAAAAAAAAAAAA yyyy-mm-dd [C]
      Key fingerprint = AAAA AAAA AAAA AAAA AAAA  AAAA AAAA AAAA AAAA AAAA
uid                   [ultimate] Given Last (nick) mailbox@domain.com>
…
sub   rsa4096/0xBBBBBBBBBBBBBBBB yyyy-mm-dd [S]
sub   rsa4096/0xCCCCCCCCCCCCCCCC yyyy-mm-dd [E]
sub   rsa4096/0xDDDDDDDDDDDDDDDD yyyy-mm-dd [A]

$ gpg -K $KEYID 
sec#  rsa4096/0xAAAAAAAAAAAAAAAA yyyy-mm-dd [C]
      Key fingerprint = AAAA AAAA AAAA AAAA AAAA  AAAA AAAA AAAA AAAA AAAA
uid                   [ultimate] Given Last (nick) mailbox@domain.com>
…
ssb>  rsa4096/0xBBBBBBBBBBBBBBBB yyyy-mm-dd [S]
ssb>  rsa4096/0xCCCCCCCCCCCCCCCC yyyy-mm-dd [E]
ssb>  rsa4096/0xDDDDDDDDDDDDDDDD yyyy-mm-dd [A]

I interpret that as:

  1. RSA master key having Certify.
  2. Separate RSA sub-keys for each of Signing, Encrypting and Authenticating.
  3. The "sub" (public) sub-keys being in the local keychain.
  4. The "ssb>" (private) sub-keys being on the YubiKey.

So, let's put a pin in that and examine your pattern:

gpg --list-keys
/home/ss/.gnupg/pubring.kbx
---------------------------
pub   ed25519 2018-11-30 [SC]
      123456789ABCDEF123456789ABCDEF12345
uid           [ unknown] something@srp.modulus
sub   cv25519 2018-11-30 [E]

I interpret that as:

  1. Elliptic curve (rather than RSA) master key having Sign and Certify.
  2. A public sub-key with Encryption in the local keychain.
  3. No information about private keys.

Quite different - agreed?

The question I ask myself is, "can I replicate that?" After a few false starts, it turns out the answer is yes.

Setup steps (Raspbian):

$ RAMDISK="/run/user/$(id -u)/ramdisk"
$ mkdir "$RAMDISK"
$ sudo mount -t tmpfs -o size=128M myramdisk "$RAMDISK"
$ sudo chown $USER:$USER "$RAMDISK"; chmod 700 "$RAMDISK"
$ export GNUPGHOME=$(mktemp -d -p "$RAMDISK")
$ cd "$GNUPGHOME"
$ wget -O $GNUPGHOME/gpg.conf https://raw.githubusercontent.com/drduh/config/master/gpg.conf
$ PASSPHRASE=$(gpg --gen-random --armor 0 24)

Generate "ECC and ECC" with "Curve 25519":

$ gpg --expert --full-generate-key
gpg: keybox '/run/user/1002/ramdisk/tmp.USf3fSZhYJ/pubring.kbx' created
Please select what kind of key you want:
   (1) RSA and RSA (default)
   (2) DSA and Elgamal
   (3) DSA (sign only)
   (4) RSA (sign only)
   (7) DSA (set your own capabilities)
   (8) RSA (set your own capabilities)
   (9) ECC and ECC
  (10) ECC (sign only)
  (11) ECC (set your own capabilities)
  (13) Existing key
  (14) Existing key from card
Your selection? 9
Please select which elliptic curve you want:
   (1) Curve 25519
   (3) NIST P-256
   (4) NIST P-384
   (5) NIST P-521
   (6) Brainpool P-256
   (7) Brainpool P-384
   (8) Brainpool P-512
   (9) secp256k1
Your selection? 1
Please specify how long the key should be valid.
         0 = key does not expire
      <n>  = key expires in n days
      <n>w = key expires in n weeks
      <n>m = key expires in n months
      <n>y = key expires in n years
Key is valid for? (0) 
Key does not expire at all
Is this correct? (y/N) y

GnuPG needs to construct a user ID to identify your key.

Real name: Test Example
Email address: test@example.com
Comment: 
You selected this USER-ID:
    "Test Example <test@example.com>"

Change (N)ame, (C)omment, (E)mail or (O)kay/(Q)uit? O
We need to generate a lot of random bytes. It is a good idea to perform
some other action (type on the keyboard, move the mouse, utilize the
disks) during the prime generation; this gives the random number
generator a better chance to gain enough entropy.
We need to generate a lot of random bytes. It is a good idea to perform
some other action (type on the keyboard, move the mouse, utilize the
disks) during the prime generation; this gives the random number
generator a better chance to gain enough entropy.
gpg: /run/user/1002/ramdisk/tmp.USf3fSZhYJ/trustdb.gpg: trustdb created
gpg: key 0xFFA9E42FB6BD3765 marked as ultimately trusted
gpg: directory '/run/user/1002/ramdisk/tmp.USf3fSZhYJ/openpgp-revocs.d' created
gpg: revocation certificate stored as '/run/user/1002/ramdisk/tmp.USf3fSZhYJ/openpgp-revocs.d/436AA047E89984A588D05FA6FFA9E42FB6BD3765.rev'
public and secret key created and signed.

pub   ed25519/0xFFA9E42FB6BD3765 2022-06-10 [SC]
      Key fingerprint = 436A A047 E899 84A5 88D0  5FA6 FFA9 E42F B6BD 3765
uid                              Test Example <test@example.com>
sub   cv25519/0xF9B081BC3EBB4E27 2022-06-10 [E]

Pattern analysis:

$ gpg --list-keys
/run/user/1002/ramdisk/tmp.USf3fSZhYJ/pubring.kbx
-------------------------------------------------
pub   ed25519/0xFFA9E42FB6BD3765 2022-06-10 [SC]
      Key fingerprint = 436A A047 E899 84A5 88D0  5FA6 FFA9 E42F B6BD 3765
uid                   [ultimate] Test Example <test@example.com>
sub   cv25519/0xF9B081BC3EBB4E27 2022-06-10 [E]

Pretty much identical pattern to yours - agreed?

So, the first issue would seem to be to figure out why, if we both followed the DrDuh guide, I wound up with RSA with C plus S+E+A split over sub-keys, while you have elliptic curve with S+C plus a single E sub-key.

One possibility is, assuming your "2018-11-30" is true, you were working a year ahead of me so maybe the guide was different then?

Another possibility. I have another key-pair which is analogous to your pattern:

$ gpg -k 0x1111111111111111
pub   rsa4096/0x1111111111111111 2019-12-18 [SC] [expires: yyyy-mm-dd]
      Key fingerprint = 1111 1111 1111 1111 1111  1111 1111 1111 1111 1111
uid                   [ unknown] Given Last (nick) mailbox@domain.com>
sub   rsa4096/0x2222222222222222 2019-12-18 [E] [expires: yyyy-mm-dd]

$ gpg -K 0x1111111111111111
sec   rsa4096/0x1111111111111111 2019-12-18 [SC] [expires: yyyy-mm-dd]
      Key fingerprint = 1111 1111 1111 1111 1111  1111 1111 1111 1111 1111
uid                   [ unknown] Given Last (nick) mailbox@domain.com>
ssb   rsa4096/0x2222222222222222 2019-12-18 [E] [expires: yyyy-mm-dd]

Those are from Keybase. RSA but the SC plus E is the same as yours. I generated and exported those, and then used them to sign the master key I was generating for the YubiKey. Why? For no better reason than that it seemed like a good idea at the time. Perhaps you did something similar?

While the steps I outlined in my earlier reply let me get going on a new machine given only my public keys plus the YubiKey, any time I want to do something more serious, I need to go back to the snapshot of the master-key generation just before the private keys were transferred to the YubiKey. That's Backup in the DrDuh guide.

I'm afraid that I didn't go to quite the extremes in the guide:

$ BACKUP="$RAMDISK/$(date +%F)-$KEYID.tar.gz"
$ tar -zcf "$BACKUP" .

then I saved that .tar.gz into an encrypted disk image. The truly paranoid would probably clutch their worry-beads but…

Anyway, given this backup, I can restore to the moment before the private keys were transferred to the YubiKey. That means I can edit whatever needs to be edited and then repeat the basic process of:

  1. Take another backup.
  2. Transfer the (updated) private keys to the first YubiKey.
  3. Restore the backup.
  4. Transfer the (updated) private keys to the second YubiKey.
  5. Save the backup into the encrypted disk image ready for next time.

Unless you skipped the "make a backup" step or have since lost the backup, you should be able to do the same.

The last possibility is that you see if Recovering lost GPG public keys from your YubiKey solves your problem. I have not tried it so I have no idea whether it works - please remember to report back here if it does.

If none of this helps you have an "ahah" moment, you might have to start from scratch and generate all-new keys.

drduh commented 1 year ago

Please reopen if there's still an issue to discuss.

vorburger commented 1 year ago

I have had similar problems, found this by web searching, and wrote up a few things I learnt to fix it (for me) on https://github.com/vorburger/vorburger-dotfiles-bin-etc/blob/main/docs/yubikey.md#troubleshooting; perhaps this will be useful for others stumbling over this in the future.