6

I recently got a Yubikey and loaded keys onto it following the directions here. gpg successfully reads and writes to the card, and I can see the key fingerprints from it it. However, when I try to use gpg --edit-card then fetch to get the key stubs, nothing happens. There is no error, but also my keys do not appear.

When I check journalctl -f, there is a message from dirmngr:

Apr 14 12:02:25 {snip} gpg-agent[1816]: card has S/N: D27{...snip...}0000
Apr 14 12:02:33 {snip} dirmngr[1823]: command 'KS_GET' failed: Server indicated a failure <Unspecified source>

man gpg sends me to the gnupg.org documentation, which gives instructions for transferring keys to the card (Section 5.2.2), but only says "You can sign, de- and encrypt files the usual way". My end goal is to use pass to securely store passwords, but when I try to use it in the usual way, I see gpg: decryption failed: No secret key.

What should I do differently?

I am using Arch Linux with gnupg from the main repository, version 2.2.15-1.

For reference, here is a complete listing of my gpg session:

$ gpg --list-secret-keys
$ gpg --list-keys
$ gpg --edit-card

Reader ...........: 1050:0407:X:0
Application ID ...: D27{...snip...}0000
Version ..........: 2.1
Manufacturer .....: Yubico
Serial number ....: 0{...snip...}6
Name of cardholder: [not set]
Language prefs ...: [not set]
Sex ..............: unspecified
URL of public key : [not set]
Login data .......: [not set]
Signature PIN ....: not forced
Key attributes ...: rsa2048 rsa2048 rsa2048
Max. PIN lengths .: 127 127 127
PIN retry counter : 3 3 3
Signature counter : 0
Signature key ....: 8DD5 {...snip...} C8B3
      created ....: 2019-04-13 23:49:11
Encryption key....: B9B0 {...snip...} 9B22
      created ....: 2019-04-13 23:49:11
Authentication key: 6447 {...snip...} 21C0
      created ....: 2019-04-13 23:53:30
General key info..: [none]

gpg/card> fetch

gpg/card> quit
$ gpg --list-secret-keys
$ gpg --list-keys
3
  • The fetch command retrieves the public key from the URL stored on the card. According to your post, there is no URL entered to fetch the public key... Apr 14, 2019 at 17:21
  • I see. So does this mean that I have to upload the public key somewhere so I have a URL? Also, how can I use the private key on the card?
    – ddulaney
    Apr 14, 2019 at 22:02
  • The public key needs to be imported onto the local gpg keyring. And then the "General key info" should show the public key followed by the card's secret keys... Once gpg knows about the public key, the card's keys should work fine. If you are using the card on many machines, it's handy to post the public on a URL someplace. Apr 15, 2019 at 3:22

1 Answer 1

6

GPG Smart Card Mini-How-To

Short Answer

It seems the secret keys are properly copied to the Yubikey smart card. However, the public key is missing from the local keyring. In order for gpg to work properly, the public key must be available locally.

There are several methods to import the public key. However, there is a handy field on the smart card for storing a URL where the public key can be found. So, if the public key is placed in a publicly accessible location on the Internet, the public key can be retrieved and added to the local keyring by using the fetch option in either the gpg/card menu or the --fetch-keys URL option on the gpg command line.

Once the local keyring knows about the public key, the private keys stored on the smart card should operate normally using the set user pin to unlock the keys.

Mini-How-To

This tutorial will run through the creation of a passphraseless PGP key set, loading the secret keys on a smart card, posting the public key on the Internet, and basic use of the card.

Please note that the key included on this post is a test and demonstration key only. It has no passphrase and can be imported locally via copy and paste if so desired. However, please do not use this test key for any purpose except testing.

GPG Version

gpg --version gpg (GnuPG) 2.2.12 libgcrypt 1.8.4

Key generation

Let's generate a key to play with:

$ cat << EOF | gpg --gen-key --batch -
> Key-Type: rsa
> Key-Length: 2048
> Key-Usage: sign
> Subkey-Type: rsa
> Subkey-Length: 2048
> Name-Real: demo card
> Name-Comment: DeleteMe
> Name-Email: demo.card@domain.tld
> %no-protection
> %commit
> EOF

Here's the secret key

gpg --armor --export-secret-key demo.card@domain.tld

-----BEGIN PGP PRIVATE KEY BLOCK-----

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
NQSlYESEFuIGA3+WuBy2
=V4D1
-----END PGP PRIVATE KEY BLOCK-----

Key Listing

gpg --edit-key F1663A6A94793987

Secret key is available.

sec  rsa2048/F1663A6A94793987
     created: 2019-04-15  expires: never       usage: SC  
     trust: ultimate      validity: ultimate
ssb  rsa2048/B4559AAA0624A9CF
     created: 2019-04-15  expires: never       usage: SEA 
[ultimate] (1). demo card (DeleteMe) <demo.card@domain.tld>

Placing the Public Key online somewhere

gpg -a --export F1663A6A94793987

https://pastebin.com/raw/y8gCBFmH

Add keys and URL to card

gpg --edit-card

gpg/card> url
URL to retrieve public key: https://pastebin.com/raw/y8gCBFmH

gpg --edit-key F1663A6A94793987

gpg> keytocard
Really move the primary key? (y/N) y
Please select where to store the key:
   (1) Signature key
   (3) Authentication key
Your selection? 1

gpg> key 1

sec  rsa2048/F1663A6A94793987
     created: 2019-04-15  expires: never       usage: SC  
     trust: ultimate      validity: ultimate
ssb* rsa2048/B4559AAA0624A9CF
     created: 2019-04-15  expires: never       usage: SEA 
[ultimate] (1). demo card (DeleteMe) <demo.card@domain.tld>

gpg> keytocard
Please select where to store the key:
   (1) Signature key
   (2) Encryption key
   (3) Authentication key
Your selection? 2

gpg> save

Delete the keys from the keyring

gpg --delete-secret-keys F1663A6A94793987

sec  rsa2048/F1663A6A94793987 2019-04-15 demo card (DeleteMe) <demo.card@domain.tld>

Delete this key from the keyring? (y/N) y
This is a secret key! - really delete? (y/N) y

gpg --delete-keys F1663A6A94793987

pub  rsa2048/F1663A6A94793987 2019-04-15 demo card (DeleteMe) <demo.card@domain.tld>

Delete this key from the keyring? (y/N) y

Similar state as the OP

gpg --edit-card

Reader ...........: 04E6:xx:0
Application ID ...: D27600xxxx0190000
Version ..........: 2.1
Manufacturer .....: unknown
Serial number ....: 00000019
Name of cardholder: [not set]
Language prefs ...: [not set]
Sex ..............: unspecified
URL of public key : https://pastebin.com/raw/y8gCBFmH
Login data .......: [not set]
Signature PIN ....: forced
Key attributes ...: rsa2048 rsa2048 rsa2048
Max. PIN lengths .: 127 127 127
PIN retry counter : 3 3 3
Signature counter : 0
Signature key ....: F44A 6EA6 5E82 1743 6E83  E2C2 F166 3A6A 9479 3987
      created ....: 2019-04-15 17:49:25
Encryption key....: EB75 66CA 07FF 9C4F 94ED  9246 B455 9AAA 0624 A9CF
      created ....: 2019-04-15 17:49:25
Authentication key: [none]
General key info..: [none]

Use Keys on Card

Retrieve Public Key

gpg/card> fetch
gpg: requesting key from 'https://pastebin.com/raw/y8gCBFmH'
gpg: key F1663A6A94793987: public key "demo card (DeleteMe) <demo.card@domain.tld>" imported
gpg: Total number processed: 1
gpg:               imported: 1

gpg/card> list

Reader ...........: 04E6:xx:0
Application ID ...: D27600xxxx0190000
Version ..........: 2.1
Manufacturer .....: unknown
Serial number ....: 00000019
Name of cardholder: [not set]
Language prefs ...: [not set]
Sex ..............: unspecified
URL of public key : https://pastebin.com/raw/y8gCBFmH
Login data .......: [not set]
Signature PIN ....: forced
Key attributes ...: rsa2048 rsa2048 rsa2048
Max. PIN lengths .: 127 127 127
PIN retry counter : 3 3 3
Signature counter : 0
Signature key ....: F44A 6EA6 5E82 1743 6E83  E2C2 F166 3A6A 9479 3987
      created ....: 2019-04-15 17:49:25
Encryption key....: EB75 66CA 07FF 9C4F 94ED  9246 B455 9AAA 0624 A9CF
      created ....: 2019-04-15 17:49:25
Authentication key: [none]
General key info..: 
pub  rsa2048/F1663A6A94793987 2019-04-15 demo card (DeleteMe) <demo.card@domain.tld>
sec>  rsa2048/F1663A6A94793987  created: 2019-04-15  expires: never     
                                card-no: 7615 00000019
ssb>  rsa2048/B4559AAA0624A9CF  created: 2019-04-15  expires: never     
                                card-no: 7615 00000019

Almost Ready for Use

gpg --edit-key F1663A6A94793987

Secret key is available.

sec  rsa2048/F1663A6A94793987
     created: 2019-04-15  expires: never       usage: SC  
     card-no: 7615 00000019
     trust: unknown       validity: unknown
ssb  rsa2048/B4559AAA0624A9CF
     created: 2019-04-15  expires: never       usage: SEA 
     card-no: 7615 00000019
[ unknown] (1). demo card (DeleteMe) <demo.card@domain.tld>

What happened to the Trust of the key?

GPG stores trust separately from the key material. This trust setting is what enables the Web of Trust. So, when a given key is imported into a local keyring, that key is not assigned a trust level. However, this is easy to change interactively.

gpg --edit-key F1663A6A94793987

gpg> trust
sec  rsa2048/F1663A6A94793987
     created: 2019-04-15  expires: never       usage: SC  
     card-no: 7615 00000019
     trust: unknown       validity: unknown
ssb  rsa2048/B4559AAA0624A9CF
     created: 2019-04-15  expires: never       usage: SEA 
     card-no: 7615 00000019
[ unknown] (1). demo card (DeleteMe) <demo.card@domain.tld>

Please decide how far you trust this user to correctly verify other users' keys
(by looking at passports, checking fingerprints from different sources, etc.)

  1 = I don't know or won't say
  2 = I do NOT trust
  3 = I trust marginally
  4 = I trust fully
  5 = I trust ultimately
  m = back to the main menu

Your decision? 5
Do you really want to set this key to ultimate trust? (y/N) y

Now the key is fully ready

gpg --list-key F1663A6A94793987

pub   rsa2048 2019-04-15 [SC]
      F44A6EA65E8217436E83E2C2F1663A6A94793987
uid           [ultimate] demo card (DeleteMe) <demo.card@domain.tld>
sub   rsa2048 2019-04-15 [SEA]

Let's try it out

gpg -ear F1663A6A94793987

Hello there!

-----BEGIN PGP MESSAGE-----

hQEMA7RVmqoGJKnPAQf/V5CAzRCQ8gmAczy5i66e6w93CRYDiJ/1fNfL6ey2lYx2
cu/I3I12455Z8YjnLk3q66LW0gkhaxVX1uhtBXgjglz2RX6wMAYSDMvVs4cfIgq4
VLbW8T2y8ThdXvpGfwtgBgfFV5M2QS46RipXeF5rOCOnGeI8IUuzAC2147/qjcHG
+/wWDaker7NfY8GSgJ8OXd6kTmpZ//1zOTYvJVsE80viByv2Hx42Zu0r6e3KqgeR
qQlNA/zevYYjm4S0tkmxYoDb42gTPClNiHkJa3IXYlwYPzLCSszBsaTfHZdHl7yx
8PshF7fmE/NOO0dhHq2cV+fqPq8uT/VlNcPm3TYNxtJIAfnuTuHcorOuQNh0koML
8WWTIlLbj9OfBsZVsy5cp5ggpSLrCdPYd1g7RzEwRxu8QrWNO+pj2VRTtEZMafXq
XsKGJIgxsbJQ
=nwdE
-----END PGP MESSAGE-----

gpg -d

Please unlock the card

Number: 7615 00000019
Holder: 
PIN: 
gpg: encrypted with 2048-bit RSA key, ID B4559AAA0624A9CF, created 2019-04-15
      "demo card (DeleteMe) <demo.card@domain.tld>"
Hello there!

Use with pass

pass init F1663A6A94793987

mkdir: created directory '/home/user/.password-store/'
Password store initialized for F1663A6A94793987

pass insert password1

Enter password for password1: <qwerty>
Retype password for password1: <qwerty>

pass show password1

Please unlock the card

Number: 7615 00000019
Holder: 
PIN: 
qwerty

Usage notes

If a given password store is initialized with a key that is not located on a card. The pass script will not be able to locate the secret key if it is then moved to a smart card.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.