Migrating your GnuPG key to a nitrokey usb device

This documentation was made with gnupg 2.1.18.

Requirements for Debian stretch

apt-get install scdaemon nitrokey-app

1. Make a backup: Save public and secret keyring

The following script does a complete export of your public and private keys plus a backup of the trust database. For this you have to fill the variable KEYS= "" with the private keys. Use the command gpg --list-secret-keys to find out.

#!/bin/bash
KEYS="key1 key2 key3"
dstDir="${HOME}/backup/gnupg"

set -x

if [ -d ${dstDir} ];
then
  mkdir -p ${dstDir}
fi

for i in $KEYS
do

  gpg --armor --output ${dstDir}/export-${i}-secret-keys.asc --export-secret-keys ${i}
  gpg --armor --output ${dstDir}/export-${i}-secret-subkeys.asc --export-secret-subkeys ${i}

done

gpg --armor --output ${dstDir}/export-all-pub-keys.asc --export
gpg --export-ownertrust >${dstDir}/ownertrust.txt

After entering your passphrase, your private keys and subkeys are saved in separate *. asc files:

ls -1 ~/backup/gnupg
export-00xyz-secret-keys.asc
export-00xyz-secret-subkeys.asc
export-all-pub-keys.asc
ownertrust.txt

2. Check if the Nitrokey works

gpg --card-status

Reader ...........: xxxx:yyyy:xxxxxxxxxxxxxxxxxxxxxxxx:x
Application ID ...: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Version ..........: 2.1
Manufacturer .....: ZeitControl
Serial number ....: xxxxxxxx
Name of cardholder: [not set]
Language prefs ...: de
Sex ..............: unspecified
URL of public key : [not set]
Login data .......: [not set]
Signature PIN ....: forced
Key attributes ...: rsa2048 rsa2048 rsa2048
Max. PIN lengths .: 32 32 32
PIN retry counter : 3 0 3
Signature counter : 0
Signature key ....: [none]
Encryption key....: [none]
Authentication key: [none]
General key info..: [none]

2. Move the master and subkey to the card

The existing secret keys will be replaced by stubs. “Stub” keys are references telling to GnuPG that it can find given private keys on smart cards (including “dongles or Nitrokeys”).

My active main encrypting key is number 4 in the list.

gpg --edit-key XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX1

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

Afterwards you select with the key command your encryption key, which is to be loaded on the nitrokey. In this example, it is key number 4:

gpg> key 4
sec  rsa4096/XXXXXXXXXXXXXXX1
     created: 20XX-XX-XX  expires: 20XX-XX-XX  usage: SC
     trust: ultimate      validity: ultimate
ssb  rsa4096/XXXXXXXXXXXXXXX2
     created: 20X1-XX-XX  expired: 20X1-XX-XX  usage: E
ssb  rsa4096/XXXXXXXXXXXXXXX3
     created: 20X2-XX-XX  expired: 20X2-XX-XX  usage: E
ssb  rsa4096/XXXXXXXXXXXXXXX4
     created: 20X3-XX-XX  expired: 20X4-XX-XX  usage: E
ssb* rsa4096/XXXXXXXXXXXXXXX5
     created: 20X4-XX-XX  expires: 20XX-XX-XX  usage: E
[ultimate] (1). firstname lastname <firstname@lastname.tld>

gpg> keytocard
Please select where to store the key:
   (2) Encryption key
Your selection? 2
gpg> key 4
sec  rsa4096/XXXXXXXXXXXXXXX1
     created: 20XX-XX-XX  expires: 20XX-XX-XX  usage: SC
     trust: ultimate      validity: ultimate
ssb  rsa4096/XXXXXXXXXXXXXXX2
     created: 20X1-XX-XX  expired: 20X1-XX-XX  usage: E
ssb  rsa4096/XXXXXXXXXXXXXXX3
     created: 20X2-XX-XX  expired: 20X2-XX-XX  usage: E
ssb  rsa4096/XXXXXXXXXXXXXXX4
     created: 20X3-XX-XX  expired: 20X4-XX-XX  usage: E
ssb  rsa4096/XXXXXXXXXXXXXXX5
     created: 20X4-XX-XX  expires: 20XX-XX-XX  usage: E
[ultimate] (1). firstname lastname <firstname@lastname.tld>

Now there are signature and encryption keys on the Nitrokey. Finish with the save command and check the nitrokey:

    gpg> save

Now check, that the keys on your nitrokey:

gpg --card-status

3. Remove main encryption subkey

Since the keys are now on the nitrokey, we can remove them from the keyring:

gpg --edit-key XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX1
gpg> key 4
sec  rsa4096/XXXXXXXXXXXXXXX1
     created: 20XX-XX-XX  expires: 20XX-XX-XX  usage: SC
     trust: ultimate      validity: ultimate
ssb  rsa4096/XXXXXXXXXXXXXXX2
     created: 20X1-XX-XX  expired: 20X1-XX-XX  usage: E
ssb  rsa4096/XXXXXXXXXXXXXXX3
     created: 20X2-XX-XX  expired: 20X2-XX-XX  usage: E
ssb  rsa4096/XXXXXXXXXXXXXXX4
     created: 20X3-XX-XX  expired: 20X4-XX-XX  usage: E
ssb* rsa4096/XXXXXXXXXXXXXXX5
     created: 20X4-XX-XX  expires: 20XX-XX-XX  usage: E
[ultimate] (1). firstname lastname <firstname@lastname.tld>
gpg> delkey
Do you really want to delete this key? (y/N) y
gpg> save

4. Reimport your complete public keyring

gpg --import ~/backup/gnupg/export-all-pub-keys.asc

5. Have a look at your new key

gpg --list-secret-keys
/home/user/.gnupg/pubring.kbx
-----------------------------
sec>  rsa4096 20XX-XX-XX [SC] [expires: 20XX-XX-XX]
      XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX1
      Card serial no. = XXXX XXXXXXXX
uid           [ unknown] firstname lastname <firstname@lastname.tld>
ssb>  rsa4096 20X4-XX-XX [E] [expires: 20XX-XX-XX]

Stub can be seen in the output of --list-secret-keys through the presence of # and > after sec and ssb:

6. Test your key

7. Keep that medium in a save place

tar cfz /path/of/USB/stick/gnupg-backup.tgz ~/backup/gnupg

Destroy ~/backup/gnupg on your harddrive:

rm -rf ~/backup/gnupg

or better:

shred -vu ~/backup/gnupg/*

Inspired by this links