2020-06-18 10:59:51 -04:00
<!--
2021-03-25 06:38:48 -04:00
Title: How to encrypt, sign and decrypt messages using GnuPG on macOS
2020-10-02 09:42:15 -04:00
Description: Learn how to encrypt, sign and decrypt messages using PGP on macOS.
2020-06-18 10:59:51 -04:00
Author: Sun Knudsen < https: / / github . com / sunknudsen >
2021-01-10 10:45:20 +00:00
Contributors: Sun Knudsen < https: / / github . com / sunknudsen > , Albert < https: / / github . com / farwel >
2020-09-10 10:07:07 -04:00
Reviewers:
2020-06-18 10:59:51 -04:00
Publication date: 2020-06-18T00:00:00.000Z
2020-11-10 07:13:35 -05:00
Listed: true
2020-06-18 10:59:51 -04:00
-->
2021-03-25 06:38:48 -04:00
# How to encrypt, sign and decrypt messages using GnuPG on macOS
2020-06-18 10:59:51 -04:00
2021-03-25 06:38:48 -04:00
[](https://www.youtube.com/watch?v=mE8fL5Fu8x8 "How to encrypt, sign and decrypt messages using GnuPG on macOS")
2020-06-25 13:56:31 -04:00
2021-03-25 06:38:48 -04:00
> WARNING: this is a “getting started” guide. For hardened guide, see https://github.com/drduh/YubiKey-Guide
## Caveats
- When copy/pasting commands that start with `$` , strip out `$` as this character is not part of the command
2020-06-18 10:59:51 -04:00
2020-12-31 10:35:49 -05:00
## Setup guide
2020-06-18 10:59:51 -04:00
2020-08-10 19:35:31 -04:00
### Step 1: install [Homebrew](https://brew.sh/)
2020-06-18 10:59:51 -04:00
```shell
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install.sh)"
```
2020-09-10 10:10:51 -04:00
### Step 2: disable Homebrew analytics
2020-06-18 10:59:51 -04:00
```shell
brew analytics off
```
2020-08-10 19:35:31 -04:00
### Step 3: install [GnuPG](https://gnupg.org/)
2020-06-18 10:59:51 -04:00
```shell
brew install gnupg
```
2020-08-10 19:35:31 -04:00
### Step 4: generate PGP key pair
2020-06-18 10:59:51 -04:00
2020-08-05 17:14:52 -04:00
```console
2020-06-18 10:59:51 -04:00
$ gpg --full-generate-key
2021-03-25 06:38:48 -04:00
gpg (GnuPG) 2.2.27; Copyright (C) 2021 Free Software Foundation, Inc.
2020-06-18 10:59:51 -04:00
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
2020-12-11 08:39:56 -05:00
gpg: directory '/Users/sunknudsen/.gnupg' created
gpg: keybox '/Users/sunknudsen/.gnupg/pubring.kbx' created
2020-06-18 10:59:51 -04:00
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)
(14) Existing key from card
Your selection? 1
RSA keys may be between 1024 and 4096 bits long.
2021-03-25 06:38:48 -04:00
What keysize do you want? (3072) 4096
2020-06-18 10:59:51 -04:00
Requested keysize is 4096 bits
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) 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: John Doe
Email address: john@example .net
Comment:
You selected this USER-ID:
"John Doe < john @example .net > "
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.
2020-12-11 08:39:56 -05:00
gpg: /Users/sunknudsen/.gnupg/trustdb.gpg: trustdb created
2021-03-25 06:38:48 -04:00
gpg: key DFCECB410CE8A745 marked as ultimately trusted
2020-12-11 08:39:56 -05:00
gpg: directory '/Users/sunknudsen/.gnupg/openpgp-revocs.d' created
2021-03-25 06:38:48 -04:00
gpg: revocation certificate stored as '/Users/sunknudsen/.gnupg/openpgp-revocs.d/E1B962BF7B5577A7B8021D18DFCECB410CE8A745.rev'
2020-06-18 10:59:51 -04:00
public and secret key created and signed.
2021-03-25 06:38:48 -04:00
pub rsa4096 2021-03-24 [SC]
E1B962BF7B5577A7B8021D18DFCECB410CE8A745
2020-06-18 10:59:51 -04:00
uid John Doe < john @example .net >
2021-03-25 06:38:48 -04:00
sub rsa4096 2021-03-24 [E]
2020-06-18 10:59:51 -04:00
```
2021-04-04 07:26:20 -04:00
### Step 5: back up `~/.gnupg` folder (learn how [here](../how-to-backup-and-encrypt-data-using-rsync-and-veracrypt-on-macos))
2020-06-18 10:59:51 -04:00
2021-03-25 06:38:48 -04:00
> Heads-up: files stored in `~/.gnupg` include private keys which, if lost, results in loosing one’ s cryptographic identity (safeguard backup carefully).
2020-06-18 10:59:51 -04:00
2020-12-03 06:29:52 -05:00
👍
2020-06-18 10:59:51 -04:00
---
## Usage guide
2020-08-10 19:35:31 -04:00
### Export John’ s PGP public key
2020-06-18 10:59:51 -04:00
```shell
gpg --armor --export john@example .net > ~/Desktop/john.asc
```
2021-03-25 06:38:48 -04:00
### Import Sun’ s public key using key server…
2020-06-18 10:59:51 -04:00
2021-03-25 06:38:48 -04:00
```console
$ gpg --keyserver hkps://keys.openpgp.org --recv-keys 0xC1323A377DE14C8B
gpg: key 0xC1323A377DE14C8B: public key "Sun Knudsen < hello @sunknudsen .com > " imported
gpg: Total number processed: 1
gpg: imported: 1
2020-06-18 10:59:51 -04:00
```
2021-03-25 06:38:48 -04:00
imported: 1
2020-06-18 10:59:51 -04:00
2021-03-25 06:38:48 -04:00
👍
### …or using public key URL
```console
$ curl https://sunknudsen.com/sunknudsen.asc | gpg --import
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 6896 100 6896 0 0 11589 0 --:--:-- --:--:-- --:--:-- 11570
gpg: key 0xC1323A377DE14C8B: public key "Sun Knudsen < hello @sunknudsen .com > " imported
gpg: Total number processed: 1
gpg: imported: 1
2020-06-18 10:59:51 -04:00
```
2021-03-25 06:38:48 -04:00
imported: 1
👍
### Verify Sun’ s PGP public key using its fingerprint
2020-06-18 10:59:51 -04:00
2020-08-05 17:14:52 -04:00
```console
2020-06-18 10:59:51 -04:00
$ gpg --fingerprint hello@sunknudsen .com
gpg: checking the trustdb
gpg: marginals needed: 3 completes needed: 1 trust model: pgp
gpg: depth: 0 valid: 1 signed: 0 trust: 0-, 0q, 0n, 0m, 0f, 1u
pub rsa4096 2019-10-17 [C]
C4FB DDC1 6A26 2672 920D 0A0F C132 3A37 7DE1 4C8B
uid [ unknown] Sun Knudsen < hello @sunknudsen .com >
2021-03-25 06:38:48 -04:00
sub rsa4096 2019-10-17 [E] [expires: 2021-10-25]
sub rsa4096 2019-10-17 [A] [expires: 2021-10-25]
sub rsa4096 2019-10-17 [S] [expires: 2021-10-25]
2020-06-18 10:59:51 -04:00
```
2021-03-25 06:38:48 -04:00
Open https://sunknudsen.com/, https://github.com/sunknudsen/pgp-public-key and https://www.youtube.com/sunknudsen/about and make sure above fingerprint (`C4FB DDC1 6A26 2672 920D 0A0F C132 3A37 7DE1 4C8B` ) matches published fingerprints.
2020-06-18 10:59:51 -04:00
👍
2020-08-10 19:35:31 -04:00
### Paste, encrypt and sign message (enter line break and use command `ctrl+d` to quit edit mode)
2020-06-18 10:59:51 -04:00
2020-08-05 17:14:52 -04:00
```console
2021-03-12 14:08:02 -05:00
$ gpg --encrypt --sign --armor --output ~/Desktop/encrypted.asc --recipient john@example .net --recipient hello@sunknudsen .com
2020-06-18 10:59:51 -04:00
gpg: 5574F4B0B0F67D7F: There is no assurance this key belongs to the named user
sub rsa4096/5574F4B0B0F67D7F 2019-10-17 Sun Knudsen < hello @sunknudsen .com >
Primary key fingerprint: C4FB DDC1 6A26 2672 920D 0A0F C132 3A37 7DE1 4C8B
Subkey fingerprint: 35A2 7551 E77C 3ED9 8527 032A 5574 F4B0 B0F6 7D7F
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
This is a test!
```
2020-08-10 19:35:31 -04:00
### Decrypt message to stdout and decode quoted-printable characters
2020-06-18 10:59:51 -04:00
2020-08-05 17:14:52 -04:00
```console
2021-01-10 09:49:15 +01:00
$ gpg --decrypt ~/Desktop/encrypted.asc | perl -MMIME::QuotedPrint -0777 -nle 'print decode_qp($_)'
2020-06-18 10:59:51 -04:00
gpg: encrypted with 4096-bit RSA key, ID 5574F4B0B0F67D7F, created 2019-10-17
"Sun Knudsen < hello @sunknudsen .com > "
2021-03-25 06:38:48 -04:00
gpg: encrypted with 4096-bit RSA key, ID D21EDF2B2BC20129, created 2021-03-24
2020-06-18 10:59:51 -04:00
"John Doe < john @example .net > "
2021-03-25 06:38:48 -04:00
gpg: Signature made Wed 24 Mar 11:04:49 2021 EDT
gpg: using RSA key E1B962BF7B5577A7B8021D18DFCECB410CE8A745
2020-06-18 10:59:51 -04:00
gpg: Good signature from "John Doe < john @example .net > " [ultimate]
This is a test!
```
2021-03-25 06:38:48 -04:00
Good signature
👍
2020-08-10 19:35:31 -04:00
### Clear passphrase from GnuPG cache
2020-06-18 10:59:51 -04:00
```shell
gpg-connect-agent reloadagent /bye
```
2021-03-14 09:15:46 -04:00
> Heads-up: when sending [encrypted messages](#paste-encrypt-and-sign-message-enter-line-break-and-use-command-ctrld-to-quit-edit-mode), don’ t forget to include your [public key](#export-johns-pgp-public-key).