Nitrokey 3: Importing GPG keys

Previous posts:

Export keys

In the previous post we created a revocation certificate that needs to be backed up. So far we are still working on the same read-only operating system. To back up the keys (primary key, sub-keys and public key) we have first to export them:

$ gpg --armor --export-secret-keys 0123456789ABCDEF > secret_keys.gpg
$ gpg --armor --export-secret-subkeys 0123456789ABCDEF > secret_subkeys.gpg
$ gpg --armor --export 0123456789ABCDEF > public_key.gpg

All those generated files should be put in a safe place that no one else can access (preferably somewhere offline, and preferably 2 copies in 2 distinct places).

In fact the primary key will not be transferred to the smart card, so the only copies we will have are those backups.

The public key on the other hand, should be easily reachable. You can put it on your website or send it to a public keys server:

$ gpg --send-key 0123456789ABCDEF

At the time of writing this post, the default server was hkps://, you can specify another one with the argument --keyserver when sending the key.

Initialize the Nitrokey

First check that gpg recognize the Nitrokey:

$ gpg --card-status
Reader ...........: …
Application ID ...: …
Application type .: OpenPGP
Version ..........: 3.4
Manufacturer .....: unknown
Serial number ....: …
Name of cardholder: [not set]
Language prefs ...: [not set]
Salutation .......: 
URL of public key : [not set]
Login data .......: [not set]
Signature PIN ....: forced
Key attributes ...: rsa4096 rsa4096 rsa4096
Max. PIN lengths .: 127 127 127
PIN retry counter : 3 0 3
Signature counter : 0
KDF setting ......: off
Signature key ....: [none]
Encryption key....: [none]
Authentication key: [none]
General key info..: [none]

First thing to do is a factory reset to be sure nothing is left from a previous configuration or if someone “played” with it before:

$ gpg --card-edit
> admin
Admin commands are allowed

> factory-reset

Set the admin PIN, then the “normal” PIN, and the reset code:

$ gpg --card-edit
> admin
Admin commands are allowed

> passwd
1 - change PIN
2 - unblock PIN
3 - change Admin PIN
4 - set the Reset Code
Q - quit

Your selection?

> 3 # change admin PIN (default is 12345678)
> 1 # change normal PIN (default is 123456)
> 4

You can also change the name, language and salutation with the commands name, lang and salutation.

If you put your public key on a public website, you can add the URL into the smart card:

$ gpg --card-edit
> admin
Admin commands are allowed

> url
URL to retrieve public key:

Send the sub-keys to the Nitrokey

$ gpg --expert --edit-key 0123456789ABCDEF
> key 1 # to select first subkey (signature) (a * should be displayed next to it)
> keytocard
> 1 # to put the key in the signature key slot on the card
> key 1 # to deselect first subkey
> key 2 # to select second subkey (encryption)
> keytocard
> 2 # to put the key in the encryption key slot on the card
> key 2
> key 3
> keytocard
> 3 # to put the key in the authentication key slot on the card

If you did the operations on a stateful operating system, don’t forget to delete the keys:

$ gpg --delete-secret-keys 0123456789ABCDEF
$ gpg --delete-keys 0123456789ABCDEF


Time to leave the read-only operating system and go to an everyday computer. After installing gnupg with sudo apt install gnupg scdaemon, the gpg --list-secret-keys command should return nothing.

There are 2 ways to import the public key and make sure it’s linked to the Nitrokey:

  • by importing the public key directly from a file (like the backup file created earlier):

    $ gpg --import public_key.gpg
    $ gpg --card-status
  • or fetching the public key from the URL in the smart card (if you set it up earlier):

    $ gpg --card-edit
    $ fetch

Now gpg --list-secret-keys should display the keys.

At this point it’s a good idea to mark the key as ultimately trusted given it’s your own key:

$ gpg --edit-key 0123456789ABCDEF
gpg> trust
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

Multiple smart cards

We loaded the keys on a smart card, but what about loading them on multiple smart cards? That could be a safe way to have a kind of backup. Obviously the procedure is the same to load the keys on the other smart cards.

The issue is that it won’t work 🙁.

GnuPG remembers the key serial number and will ask for the same one. The data is stored in ~/.gnupg/private-keys-v1.d, so deleting the right files in there will allow to swap to another smart card, but it’s a bit of an ugly hack.

Version 2.3 of GnuPG seems to improve the behavior with multiple smart cards, but as I have GnuPG 2.2, I can’t confirm it works.

Next steps:

Comments Add one by sending me an email.