GnuPG

Enable Javascript to display Table of Contents.

Setting up GnuPG

Initially you have to create an own key pair. It is suggested to use the default values, except setting the validity to 1y (one year).
$ gpg --full-gen-key
gpg (GnuPG) 2.2.4; Copyright (C) 2017 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.
[...]
$
In a second step we can export the public key - e.g. to share it with collegues/friends.
$ gpg --export --armor --output gpg_public_krach_2021.key
$
Then create a backup of your keys, the revocation certificate and the ownertrust:
$ gpg -a --export my@email > gpg_backup_public_krach_$(date '+%F').txt
$ gpg -a --export-secret-keys my@email > gpg_backup_secret_krach_$(date '+%F').txt
$ gpg --export-ownertrust > gpg_backup_ownertrust_krach_$(date '+%F').txt
$ gpg --gen-revoke --armor --output gpg_backup_revocation_krach_$(date '+%F').asc user-id
$
In the next step print your current GnuPG database, then rename it (so that GnuPG cannot access it):
$ gpg --list-secret-keys
$ mv .gnupg gnupg_todelete
$ gpgconf --kill gpg-agent   # restart agent
$
Since a backup is only a backup if we have tested it, we import the backup and compare the database with the renamed one:
$ gpg --import gpg_backup_secret_krach_*.txt
[...]
gpg: Total number processed: 1
gpg:               imported: 1
gpg:       secret keys read: 1

$ gpg --import-ownertrust gpg_backup_ownertrust_krach_*.txt
gpg: inserting ownertrust of 6

$ gpg --list-secret-keys
[...]
$
If the import was successful, please delete the renamed GnuPG database.

Source: wiki.archlinux.org

Extending Expire-Date of Public Key

You simply change the expire-date. In case that you have distributed the old public key, you may want to distribute the new public key (with the new date).
$ gpg --list-keys
/home/krach/.gnupg/pubring.kbx
------------------------------
pub   rsa3072 2021-01-18 [SC] [expires: 2022-01-18]
      9827349823749283749287349273498723947234
uid           [ultimate] Karl Krach <my@email>
sub   rsa3072 2021-01-18 [E] [expires: 2022-01-18]


$
$
$ gpg --edit-key 9827349823749283749287349273498723947234
gpg (GnuPG) 2.2.4; Copyright (C) 2017 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.

Secret key is available.

sec  rsa3072/9988776655443322
     created: 2021-01-18  expires: 2022-01-18  usage: SC  
     trust: ultimate      validity: ultimate
ssb  rsa3072/1234567890123456
     created: 2021-01-18  expires: 2022-01-18  usage: E   
[ultimate] (1). Karl Krach <my@email>

gpg> key 1234567890123456

sec  rsa3072/9988776655443322
     created: 2021-01-18  expires: 2022-01-18  usage: SC  
     trust: ultimate      validity: ultimate
ssb* rsa3072/1234567890123456
     created: 2021-01-18  expires: 2022-01-18  usage: E   
[ultimate] (1). Karl Krach <my@email>

gpg> expire 
Changing expiration time for a subkey.
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) 1y
Key expires at Wed 11 Jan 2023 10:31:26 AM CET
Is this correct? (y/N) y

sec  rsa3072/9988776655443322
     created: 2021-01-18  expires: 2022-01-18  usage: SC  
     trust: ultimate      validity: ultimate
ssb* rsa3072/1234567890123456
     created: 2021-01-18  expires: 2023-01-11  usage: E   
[ultimate] (1). Karl Krach <my@email>

gpg> save
$ 
Maybe you want to update your backup - but imho this step is not needed.

Source: sites.lafayette.edu

Extending Expire-Date of Secret Key

$ gpg --list-keys
/home/krach/.gnupg/pubring.kbx
------------------------------
pub   rsa3072 2021-01-18 [SC] [expired: 2024-01-05]
      9827349823749283749287349273498723947234
uid           [ expired] Karl Krach <my@email>
When you have updated your sub-key (public key) but your secret key is expired, you can simply fix this with the following commands:
$ gpg --edit-key 9827349823749283749287349273498723947234
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.

Secret key is available.

sec  rsa3072/9988776655443322
     created: 2021-01-18  expired: 2022-01-18  usage: SC
     trust: ultimate      validity: expired
ssb  rsa3072/1234567890123456
     created: 2021-01-18  expired: 2024-01-05  usage: E
[ expired] (1). Karl Krach <my@email>

gpg> key 0

sec  rsa3072/9988776655443322
     created: 2021-01-18  expired: 2022-01-18  usage: SC
     trust: ultimate      validity: expired
ssb  rsa3072/1234567890123456
     created: 2021-01-18  expired: 2024-01-05  usage: E
[ expired] (1). Karl Krach <my@email>

gpg> expire
Changing expiration time for the primary key.
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) 1y
Key expires at Fri Jan  5 08:49:13 2024 UTC
Is this correct? (y/N) y

sec  rsa3072/9988776655443322
     created: 2021-01-18  expires: 2024-01-05  usage: SC
     trust: ultimate      validity: ultimate
ssb  rsa3072/1234567890123456
     created: 2021-01-18  expires: 2024-01-05  usage: E
[ultimate] (1). Karl Krach <my@email>

gpg> save
$
$
$ gpg --list-keys
/home/krach/.gnupg/pubring.kbx
------------------------------
pub   rsa3072 2021-01-18 [SC] [expires: 2024-01-05]
      9827349823749283749287349273498723947234
uid           [ultimate] Karl Krach <my@email>
sub   rsa3072 2021-01-18 [E] [expires: 2024-01-05]

$

Data Encryption/Decryption

That others can send you an encrypted file, you have to export and send them your public key:
$ gpg --export --armor --output your-name.key user-id
$
The user-id can be your fingerprint, email, name, etc.
If you have received a foreign key, you can import it:
$ gpg --import public.key
$
Encryption and decryption works as following:
$ gpg --armor --recipient user-id --encrypt my_document.pdf
$ gpg --output my_decrypted_document.pdf --decrypt my_document.pdf.asc
[...]
$
Add --default-recipient-self to make it decryptable by yourself. The --armor creates an ascii output. Use --hidden-recipient instead of --recipient to hide the recipient name/ID.

Source: wiki.archlinux.org

Using pass - The Standard Unix Password Manager

E.g. when using docker on Linux, the password store pass is needed. These are the commands:

Initialize

pass is built upon GnuPG. This means you have to setup GnuPG first. After that you can initialize the pass password store like this:
$ gpg --list-keys
/home/krach/.gnupg/pubring.kbx
------------------------------
pub   rsa3072 2021-01-18 [SC] [expires: 2024-01-05]
      9827349823749283749287349273498723947234
uid           [ultimate] Karl Krach <my@email>
sub   rsa3072 2021-01-18 [E] [expires: 2024-01-05]

$
$ pass init 9827349823749283749287349273498723947234
mkdir: created directory '/home/krach/.password-store/'
Password store initialized 9827349823749283749287349273498723947234
$
where the user-id is e.g. your GnuPG fingerprint.

Add Password

Adding a password can be done in two ways. Either adding a existing password:
$ pass insert dir/pwd
mkdir: created directory '/home/krach/.password-store/dir'
Enter password for dir/pwd: *********************************
Retype password for dir/pwd: *********************************
$
where dir/pwd is a path of your choice - e.g. 'development/docker'. The second way is to let pass generate a password for you:
$ pass generate dir/pwd 25
mkdir: created directory '/home/krach/.password-store/dir'
The generated password for dir/pwd is:
VL~#C\o]^9l?.zsO3j8[{dUAt
$

List Passwords

Passwords are listed with
$ pass ls
Password Store
├── dir
│   ├── pwd2
│   └── pwd
└── foo
    └── bar
$

Get Password

You can print the password by pass dir/pwd or better, copy it to the clipboard for 45 seconds:
$ pass -c dir/pwd
Copied dir/pwd to clipboard. Will clear in 45 seconds.
$
Imho it is important, to lock the gpg-agent again:
$ gpgconf --reload gpg-agent
$

Delete Password

The password is simply deleted by
$ pass rm dir/pwd
$

Source: passwordstore.org

Accessing SmartCards

To access a SmartCard from a standard Debian installation, you have to install pcscd (PC/SC Smart Card Daemon). See Debian OpenPGP.
root@host137:~# dmesg | tail
[ 4991.900781] usb 1-8: Product: USB SmartCard Reader
[ 4991.900784] usb 1-8: Manufacturer: Gemalto
[ 4991.900788] usb 1-8: SerialNumber: B664C2F3
root@host137:~#

kkr@host137:~$ gpg2 --list-keys
kkr@host137:~$ gpg2 --card-edit
Reader ...........: Gemalto USB Shell Token V2 (CF6E23E4) 00 00
Application ID ...: D2760001240102010005000052CB0000
[...]
gpg/card> fetch
[...]
gpg/card> quit
kkr@host137:~$ gpg2 --list-keys
[...]
uid [ unknown] WORK Microwave GmbH <support@work-microwave.com>
[...]
kkr@host137:~$ gpg2 --clearsign new.txt
[...]

Setting up SmartCard

A completely new card looks like this:
kkr@host137:~$ gpg2 --card-status
Reader ...........: 08E6:3437:B664C2F3:0
Application ID ...: D2760001240102010005000052890000
Version ..........: 2.1
Manufacturer .....: ZeitControl
Serial number ....: 00005289
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]
kkr@host137:~$

General Data

Setting up the general data:
kkr@host137:~$ gpg2 --card-edit
Reader ...........: 08E6:3437:B664C2F3:0
Application ID ...: D2760001240102010005000052890000
[...]gpg/card> admin
Admin commands are allowed
gpg/card> passwd
gpg: OpenPGP card no. D2760001240102010005000052890000 detected

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

Your selection? 1
PIN changed.

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

Your selection? 3
PIN changed.

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

Your selection? q

gpg/card> name
Cardholder's surname: WBE
Cardholder's given name:

gpg/card> url
URL to retrieve public key: http://debian.lan.work-microwave.de/gnupg_keys/aseries_publickey_01.asc
gpg/card> quit

Exporting Keys

Before exporting the keys to the smartcard, create a backup:
kkr@host137:~$ tar cfz gnupg-backup.tar.gz .gnupg
When exporting the key, it's important to NOT save change at exit - otherwise you will have the secret key only on the smartcard and have to reply your backup:
kkr@host137:~$ gpg2 --edit-key C1E49405B6DBAE8726E81B079630BA7181606A9F
gpg (GnuPG) 2.1.18; Copyright (C) 2017 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.

Secret key is available.

sec rsa4096/9630BA7181606A9F
 created: 2016-01-11 expires: never usage: SC 
 trust: unknown validity: unknown
[ unknown] (1). WORK Microwave GmbH <support@work-microwave.com>

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

sec rsa4096/9630BA7181606A9F
 created: 2016-01-11 expires: never usage: SC 
 trust: unknown validity: unknown
[ unknown] (1). WORK Microwave GmbH <support@work-microwave.com>

gpg> quit
Save changes? (y/N) n
Quit without saving? (y/N) y
kkr@host137:~$

Resetting Signature Counter

Resetting the signature counter is only possible by replacing the signature key:
kkr@host137:~$ gpg2 --edit-key C1E49405B6DBAE8726E81B079630BA7181606A9F
[...]
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: WARNING: such a key has already been stored on the card!

Replace existing key? (y/N) y
[...]
gpg> quit
Save changes? (y/N) n
Quit without saving? (y/N) y
kkr@host137:~$ gpg2 --card-status
[...]
Signature counter : 0
[...]
kkr@host137:~$ 

Trouble Shooting

Missing item in object

Error when SmartCard has no secret key (e.g. after factory reset):
kkr@host137:~$ gpg --clearsign opt.txt
gpg: signing failed: Missing item in object
gpg: opt.txt.asc: clear-sign failed: Missing item in object
kkr@host137:~$

No service

Without this daemon, GnuPG cannot access the SmartCard:
kkr@host137:~$ gpg --card-status
gpg: pcsc_establish_context failed: no service (0x8010001d)
gpg: card reader not available
gpg: OpenPGP card not available: general error
kkr@host137:~$ gpg2 --card-status
gpg: selecting openpgp failed: Card error
gpg: OpenPGP card not available: Card error
kkr@host137:~$

The installation is done with apt-get:

kkr@host137:~$ sudo apt-get install pcscd

After that installation, the Gemalto USB-token can be accessed:

kkr@host137:~$ gpg2 --card-status
Application ID ...: D2760001240102010005000052CB0000
Version ..........: 2.1
Manufacturer .....: ZeitControl
Serial number ....: 000052CB
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 ...: 2048R 2048R 2048R
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]
kkr@host137:~$

No such device

It seems that with GnuPG2 in version 2.1.18 the smart-cards need some workaround:
kkr@host137:~$ gpg2 --card-status
gpg: selecting openpgp failed: No such device
gpg: OpenPGP card not available: No such device
kkr@host137:~$ echo "disable-ccid" >> .gnupg/scdaemon.conf
kkr@host137:~$ sudo sudo killall gpg2 gpg-agent scdaemon
kkr@host137:~$ gpg2 --card-status
Reader ...........: Gemalto USB Shell Token V2 (CF6E23E4) 00 00
Application ID ...: D2760001240102010005000052CB0000
kkr@host137:~$
When it's still not working, either no Smartcard is inserted, the Smartcard doesn't work or the reader doesn't work.