1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
|
#+date: <2022-07-14 Thu 00:00:00>
#+title: Exploring GNU Privacy Guard: Secure Your Communications with GPG
#+description: An in-depth guide to GNU Privacy Guard (GPG), its history, encryption algorithms, vulnerabilities, key creation, and common use cases for secure data and email protection.
#+slug: gnupg
* The History of GPG
[[https://gnupg.org/][GNU Privacy Guard]], also known as GnuPG and GPG,
is a free ("free" as in both speech and beer) software that fully
implements the OpenPGP Message Format documented in
[[https://www.rfc-editor.org/rfc/rfc4880][RFC 4880]].
I won't go in-depth on the full history of the software in this post,
but it is important to understand that GPG is not the same as PGP
(Pretty Good Privacy), which is a different implementation of RFC 4880.
However, GPG was designed to interoperate with PGP.
GPG was originally developed in the late 1990s by
[[https://en.wikipedia.org/wiki/Werner_Koch][Werner Koch]] and has
historically been funded generously by the German government.
Now that we have all the high-level info out of the way, let's dive into
the different aspects of GPG and its uses.
* Encryption Algorithms
GPG supports a wide range of different encryption algorithms, including
public-key, cipher, hash, and compression algorithms. The support for
these algorithms has grown since the adoption of the Libgcrypt library
in the 2.x versions of GPG.
As you will be able to see below in an example of a full key generation
with the GPG command line tool, GPG recommends the following algorithms
to new users:
#+begin_src sh
Please select what kind of key you want:
(1) RSA and RSA
(2) DSA and Elgamal
(3) DSA (sign only)
(4) RSA (sign only)
(9) ECC (sign and encrypt) *default*
(10) ECC (sign only)
#+end_src
I am not doing an in-depth explanation here in order to keep the focus
on GPG and not encryption algorithms. If you want a deep dive into
cryptography or encryption algorithms, please read my other posts:
- [[../aes-encryption/][AES Encryption]] (2018)
- [[../cryptography-basics/][Cryptography Basics]] (2020)
** Vulnerabilities
As of 2022-07-14, there are a few different vulnerabilities associated
with GPG or the libraries it uses:
- GPG versions 1.0.2--1.2.3 contains a bug where "as soon as one
(GPG-generated) ElGamal signature of an arbitrary message is released,
one can recover the signer's private key in less than a second on a
PC." ([[https://www.di.ens.fr/~pnguyen/pub_Ng04.htm][Source]])
- GPG versions prior to 1.4.2.1 contain a false positive signature
verification bug.
([[https://lists.gnupg.org/pipermail/gnupg-announce/2006q1/000211.html][Source]])
- GPG versions prior to 1.4.2.2 cannot detect injection of unsigned
data. (
[[https://lists.gnupg.org/pipermail/gnupg-announce/2006q1/000218.html][Source]])
- Libgcrypt, a library used by GPG, contained a bug which enabled full
key recovery for RSA-1024 and some RSA-2048 keys. This was resolved in
a GPG update in 2017. ([[https://lwn.net/Articles/727179/][Source]])
- The [[https://en.wikipedia.org/wiki/ROCA_vulnerability][ROCA
Vulnerability]] affects RSA keys generated by YubiKey 4 tokens.
([[https://crocs.fi.muni.cz/_media/public/papers/nemec_roca_ccs17_preprint.pdf][Source]])
- The [[https://en.wikipedia.org/wiki/SigSpoof][SigSpoof Attack]] allows
an attacker to spoof digital signatures.
([[https://arstechnica.com/information-technology/2018/06/decades-old-pgp-bug-allowed-hackers-to-spoof-just-about-anyones-signature/][Source]])
- Libgcrypt 1.9.0 contains a severe flaw related to a heap buffer
overflow, fixed in Libgcrypt 1.9.1
([[https://web.archive.org/web/20210221012505/https://www.theregister.com/2021/01/29/severe_libgcrypt_bug/][Source]])
*** Platforms
Originally developed as a command-line program for *nix systems, GPG now
has a wealth of front-end applications and libraries available for
end-users. However, the most recommended programs remain the same:
- [[https://gnupg.org][GnuPG]] for Linux (depending on distro)
- [[https://gpg4win.org][Gpg4win]] for Windows
- [[https://gpgtools.org][GPGTools]] for macOS
* Creating a Key Pair
In order to create a GPG key pair, a user would first need to install
GPG on their system. If we're assuming that the user is on Fedora Linux,
they would execute the following:
#+begin_src sh
sudo dnf install gpg
#+end_src
Once installed, a user can create a new key pair with the following
command(s):
#+begin_src sh
gpg --full-generate-key
#+end_src
GPG will walk the user through an interactive setup that asks for an
algorithm preference, expiration date, name, and email to associate with
this key.
See the following example key set-up for a default key generation using
the GnuPG command-line interface:
#+begin_src sh
gpg (GnuPG) 2.3.6; 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.
Please select what kind of key you want:
(1) RSA and RSA
(2) DSA and Elgamal
(3) DSA (sign only)
(4) RSA (sign only)
(9) ECC (sign and encrypt) *default*
(10) ECC (sign only)
(14) Existing key from card
Your selection? 9
Please select which elliptic curve you want:
(1) Curve 25519 *default*
(4) NIST P-384
Your selection? 1
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: johndoe@example.com
Comment: test key
You selected this USER-ID:
"John Doe (test key) <johndoe@example.com>"
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.
gpg: revocation certificate stored as 'example.rev'
public and secret key created and signed.
pub ed25519 2022-07-14 [SC]
E955B7700FFC11EF51C2BA1FE096AACDD4C32E9C
uid John Doe (test key) <johndoe@example.com>
sub cv25519 2022-07-14 [E]
#+end_src
Please note that GUI apps may differ slightly from the GPG command-line
interface.
* Common Usage
As noted in RFC 4880, the general functions of OpenPGP are as follows:
- digital signatures
- encryption
- compression
- Radix-64 conversion
- key management and certificate services
From this, you can probably gather that the main use of GPG is for
encrypting data and/or signing the data with a key. The purpose of
encrypting data with GPG is to ensure that no one except the intended
recipient(s) can access the data.
Let's explore some specific GPG use-cases.
** Email
One of the more popular uses of GPG is to sign and/or encrypt emails.
With the use of a GPG keypair, you can encrypt a message, its subject,
and even the attachments within.
The first process, regarding the signing of a message without any
encryption, is generally used to provide assurance that an email is
truly coming from the sender that the message claims. When I send an
email, and it's signed with my public key, the recipient(s) of the
message can verify that the message was signed with my personal key.
The second process, regarding the actual encryption of the message and
its contents, works by using a combination of the sender's keys and the
recipient's keys. This process may vary slightly by implementation, but
it most commonly uses asymmetric cryptography, also known as public-key
cryptography. In this version of encryption, the sender's private key to
sign the message and a combination of the sender's keys and the
recipient's public key to encrypt the message.
If two people each have their own private keys and exchange their public
keys, they can send encrypted messages back and forth with GPG. This is
also possible with symmetric cryptography, but the process differs since
there are no key pairs.
Implementation of email encryption varies greatly between email clients,
so you will need to reference your email client's documentation to
ensure you are setting it up correctly for that specific client.
** File Encryption
As noted in the section above regarding emails, GPG enables users to be
able to send a message to each other if they are both set-up with GPG
keys. In this example, I am going to show how a user could send a file
called =example_file.txt= to another user via the recipient's email.
The sender would find the file they want to send and execute the
following command:
#+begin_src sh
gpg --encrypt --output example_file.txt.gpg --recipient \
recipient@example.com example_file.txt
#+end_src
Once received, the recipient can decrypt the file with the following
command:
#+begin_src sh
gpg --decrypt --output example_file.txt example_file.txt.gpg
#+end_src
** Ownership Signatures
One important aspect of GPG, especially for developers, is the ability
to sign data without encrypting it. For example, developers often sign
code changes when they commit the changes back to a central repository,
in order to display ownership of who made the changes. This allows other
users to look at a code change and determine that the change was valid.
In order to do this using [[https://git-scm.com][Git]], the developer
simply needs to alter the =git commit= command to include the =-S= flag.
Here's an example:
#+begin_src sh
git commit -S -m "my commit message"
#+end_src
As an expansion of the example above, Git users can configure their
environment with a default key to use by adding their GPG signature:
#+begin_src sh
git config --global user.signingkey XXXXXXXXXXXXXXXX
#+end_src
If you're not sure what your signature is, you can find it titled =sig=
in the output of this command:
#+begin_src sh
gpg --list-signatures
#+end_src
** File Integrity
When a person generates a signature for data, they are allowing users
the ability to verify the signature on that data in the future to ensure
the data has not been corrupted. This is most common with software
applications hosted on the internet - developers provide signatures so
that users can verify a website was not hijacked and download links
replaced with dangerous software.
In order to verify signed data, a user needs to have:
1. The signed data
2. A signature file
3. The public GPG key of the signer
Once the signer's public key is imported on the user's system, and they
have the data and signature, they can verify the data with the following
commands:
#+begin_src sh
# If the signature is attached to the data
gpg --verify [signature-file]
# If the signature is detached as a separate file from the data
gpg --verify [signature-file] [original-file]
#+end_src
*** Finding Public Keys
In order to use GPG with others, a user needs to know the other user(s)
keys. This is easy to do if the user knows the other user(s) in person,
but may be hard if the relationship is strictly digital. Luckily, there
are a few options. The first option is to look at a user's web page or
social pages if they have them.
Otherwise, the best option is to use a keyserver, such as:
- [[https://pgp.mit.edu][pgp.mit.edu]]
- [[https://keys.openpgp.org][keys.openpgp.org]]
|