We will introduce the OpenPGP (Pretty Good Privacy) specification for
cryptographically secure communications, with an emphasis on informed
use of the gnupg
suite of command-line utilities.
Computers essentially operate based on the results of communications: the software you run, the people you know, the amount of money in your bank account, how to use the money in your bank account, is all in essence digital communications. The authenticity and security of all of this is dependent on software cryptosystems, and in particular, on the notion of asymmetric cryptography.
You might know cryptography in the sense of symmetric ciphers:
there is a secret SEC
. To encrypt a message M
, called the
cleartext, you apply a mathematical operation enc(SEC, M)
. The
result is the ciphertext X
.
Anyone who knows the same secret SEC
can apply a mathematical
operation dec(SEC, X)
to recreate the message, that is,
dec(SEC, X) = dec(SEC, enc(SEC, M)) = M
Exercise: implement the Caesar cipher as a function enc(n, M)
in
python, which advances each letter of the string M
by n
(here
playing the role of SEC
): enc(1, "abc") = "bcd"
and enc(1, "xyz") = "yza"
, etc.
Asymmetric cryptography works differently: there is a pair of related
keys (numbers), for now call them A
and B
. Just like with
symmetric cryptography, there is a mathematical operation RSA(key, x)
.
The keys A
and B
have a special relationship: if a message is
encrypted with A
, it is decrypted by B
, and vice-versa:
RSA(A, RSA(B, M)) = M
RSA(B, RSA(A, M)) = M
Without B
, RSA(A, x)
cannot be decrypted, even with A
.
The first system for constructing such A
, B
, and RSA
is called the
[Rivest-Shamir-Adelman algorithm], after the three authors. Now there
are many such systems, not all of which can properly be called RSA.
Using this algorithm, we can develop a trust system: call one key in
the pair the "public" key P
; it is made available to all. The other
key, S
for "secret", is kept secret by the owner, never revealed to
anyone.
Keypairs are often referred to by the SHA1 hash of the public key, called the fingerprint; this is a sequence of 40 hexadecimal (0-9A-F) digits, usually displayed in 10 blocks of 4 digits:
0123 4567 89AB CDEF 0123 4567 89AB CDEF FFFF 0000
A nickname for the PGP identity is the handle, the last two
blocks: FFFF0000
.
If you want to know whether two public keys are the same, compare the fingerprints. It is very possible for two keys to have the same handles; in fact, if you start with a handle, it is feasible to generate multiple keys with this handle.
This is why the handle is a poor choice for identifying a potentially untrusted key. The same is not feasible with the fingerprint; thus, if two keys have the same fingerprint, you can be confident they are the same keys.
Anyone who wishes to send a message M
to the key owner can compute
RSA(P, M)
; only the matching secret key will be able to decrypt.
enc >--------->---------> dec
/ \
/ RSA(P, -) RSA(S, -) \
/ \
P You Me P,S
Similarly, if the owner wishes to publish a message which has their
approval indisputably, they may compute a hash H = H(M)
of the
message, and encrypt it with their secret key B
to get the
digital signature sig = RSA(S, H)
; they send this alongside
their message. The pair sigM = (M, sig)
is called a signed message.
Anyone who doubts the authenticity of the message can hash the message
to get H(M)
and compute RSA(P, sig) = RSA(P, RSA(S, H)) = H
; if they
H(M) = RSA(P, sig)
, then the owner must have approved the message:
the key P
can only decrypt messages encrypted by S
, so the sender
must have S
.
(We encrypt H(M)
instead of M
so that the size of sig
doesn't
grow with the size of M
.)
P You Me P,S
\ /
\ RSA(P, -) RSA(S, -) /
\ /
verify <---------<---------< sign
Exercise Who can verify the signature? Who can decrypt the message? Why?
There are two fundamental assumptions in this trust system; these are called the validity assumptions:
S
S
If both assumptions are believed to hold, then we say you believe the key is valid for me.
A major strategy in attacking asymmetric cryptosystems is to convince
the target to use a public key P
for which the attacker holds the
secret part S
. They can do this by tricking you into using the wrong
different public key (attacking assumption 1), or stealing my secret
key (attacking assumption 2).
Assumption 1 can be supported using a protocol called "certification," (explanation follows).
One strategy for providing assumption 1 is to verify the public key with an in-person meet. But what if the attacker replaces the public key on your computer, after you have checked it? (This sounds unlikely, but it is a real-world attack!)
You can keep a written record; but what if your attacker changes the record, also? The solution, perhaps obviously, is to sign the record.
A certification is a signed message stating "I have verified Person N has public key P". If you only trust keys for which you have made a certification, then you can trust the keys as far as you trust the security of the RSA algorithm and the security of your own secret keys.
Here is the protocol for certification: first you verify in-person
that I use public key P
. Then you make the certification yourself
using your keys (P'
, S'
):
cert.M = "Fran certifies that Nick has public key " + P_Nick # here P_Nick is my public key
cert.sig = RSA(H(cert.M), S_Fran) # and S_Fran is *Fran's* secret key
Fran can post this certification publically, and anyone can use Fran's
public key P_Fran
to verify that Fran has checked my public key.
(Assuming P_Fran
is valid for them!)
Whether another person trusts your key is a different matter!
But assuming they trust your key, and they believe your certification message that "Nick has public key P", then they will be able to indirectly trust my key.
You can build a graph in which nodes are names+keys and edges are certifications. If you have some faith in the people you have certified, you might be willing to assign validity to keys for people which you haven't personally certified, but which others have.
cert
(Nick) --------- (Danya)
trust / .
+cert / .
/ . valid (no cert)
(Fran)
Here, Fran has certified my key, and I have certified Danya's key. Further, Fran has decided to trust me to certify others. From this, Fran believes he has a key valid for Danya, even though he has never certified this key.
This happens in the real world constantly: you decide the reputability of businesses, doctors, friends, schools, books, all based on the recommendations of others.
Pretty Good Privacy is a specification for the use of asymmetric cryptography in the ways described above. We describe a simplified version of the specification; for all the details, we direct the reader to RFC4880 and successors.
In PGP every user has a PGP id, which consists of several components:
Master keypair
The keypair which binds (a kind of internal certification) subkeypairs, and performs Certify operations. Its fingerprint uniquely identifies this PGP identity.
List of user ids
A list of identities for the user; these are typically of the form
Full Name <handle@domain.com>
, though you can have urls,
pictures, or any other (small) identifying data.
Subkeypairs
Additional keypairs for encryption and authentication, separated for compartmentalisation (see below).
Certifications
A list of certifications (frequently called "key signatures") other PGP ids have made of this PGP id.
A PGP identity has multiple keypairs to "compartmentalise" keys based on risk and value. If you use the same keypair for encryption and for signatures, then any compromise for one purpose (e.g., a hacker or court wants you to release a decryption key) would compromise the other (so the hacker or court gains the ability to forge your signature!).
Capabilities are broken up in the following way:
PGP ids are frequently referred to by the fingerprint of the master keypair.
Here is a schematic model of a PGP identity:
PGP id ...FFFF0000
|----------------------------------|
| master keypair [CS__] |
|----------------------------------|
| user ids |
| Nick Howell <nlhowell@gmail.com> | -- certifications (read below)
| Nick Howell <nlhowell@yandex.ru> | -- no certifications
|----------------------------------|
| authenticate keypair [___A] |
|----------------------------------|
| encrypt keypair [__E_] |
|----------------------------------|
| certifications |
| Nick Howell <nlhowell@gmail.com> |
| by ....EEEE1111 |
| |
| Nick Howell <nlhowell@gmail.com> |
| by ....DDDD2222 |
|----------------------------------|
Here ...EEEE1111
and ...DDDD2222
are fingerprints of PGP ids of
users who have issued a certification of our PGP id; the owners of
these PGP ids made these certifications, and we carry them as a sort
of "letter of introduction," some evidence that this key is reputable.
GNU Privacy Guard is a libre software implementation of the PGP specification.
The main way of interacting with GnuPG is with the command-line tool
gpg
. It comes by default on Linux and BSD distributions; see their
homepage for installation on Mac or Windows.
Please check that you have a modern version of gpg
:
$ gpg --version
gpg (GnuPG) 2.2.8
libgcrypt 1.8.3
Copyright (C) 2018 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <https://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Home: /home/nlhowell/.gnupg
Supported algorithms:
Pubkey: RSA, ELG, DSA, ECDH, ECDSA, EDDSA
Cipher: IDEA, 3DES, CAST5, BLOWFISH, AES, AES192, AES256, TWOFISH,
CAMELLIA128, CAMELLIA192, CAMELLIA256
Hash: SHA1, RIPEMD160, SHA256, SHA384, SHA512, SHA224
Compression: Uncompressed, ZIP, ZLIB, BZIP2
Versions of gpg
older than 2.1.0
have serious design limitations,
and are not supported. If your gpg
version reads below 2.0.0
you
may check if you have a gpg2
command.
To generate a new PGP identity, run
$ gpg --gen-key
gpg (GnuPG) 2.2.8; Copyright (C) 2018 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.
gpg: keybox '/tmp/test/pubring.kbx' created
Note: Use "gpg --full-generate-key" for a full featured key generation dialog.
GnuPG needs to construct a user ID to identify your key.
Real name: Nick Howell
Email address: nlhowell@gmail.com
You selected this USER-ID:
"Nick Howell <nlhowell@gmail.com>"
Change (N)ame, (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.
<PASSPHRASE DIALOG>
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: /tmp/test/trustdb.gpg: trustdb created
gpg: key 31496C2CC0FD482F marked as ultimately trusted
gpg: directory '/tmp/test/openpgp-revocs.d' created
gpg: revocation certificate stored as '/tmp/test/openpgp-revocs.d/1C27E72BE87CF18EF76DF12131496C2CC0FD482F.rev'
public and secret key created and signed.
pub rsa2048 2018-11-14 [SC] [expires: 2020-11-13]
1C27E72BE87CF18EF76DF12131496C2CC0FD482F
uid Nick Howell <nlhowell@gmail.com>
sub rsa2048 2018-11-14 [E] [expires: 2020-11-13]
Here is an annotated view of the final output:
(2) (3) (4) (5)
(1) pub rsa2048 2018-11-14 [SC] [expires: 2020-11-13]
(6) 1C27E72BE87CF18EF76DF12131496C2CC0FD482F
(7) uid Nick Howell <nlhowell@gmail.com>
(2) (3) (4) (5)
(8) sub rsa2048 2018-11-14 [E] [expires: 2020-11-13]
pub
are master keypairs.rsa2048
means RSA with 2048-bit keys. There are a handful of
other algorithms.sub
are subkeypairs; (2)-(5) apply.Thus for me this command generated pgp id
1C27 E72B E87C F18E F76D F121 3149 6C2C C0FD 482F
or c0fd482f
for short.
There are many options for publication of PGP keys:
a network of keyservers, the most visible being
keys.openpgp.org
; upload your key there!
Note that by default, keyservers will not show your name or e-mail publically, only the fingerprint.
supporting service providers; try associating your PGP identities with Gitlab/Github
Gitlab and Github provide the ability to associate your PGP
identity with your account. You can then use gpg
to sign your
commits and pushes.
hosted on a website
sent by e-mail/chat/etc
First steps are to export to plain-text:
$ gpg --armor --export c0fd482f # use your own handle
-----BEGIN PGP PUBLIC KEY BLOCK-----
mQENBFvr2AsBCADQ1OxX5bQf5ebpI4a6fXxiL7PggyYk8sc49uCYYOgndleauMkv
Uqjn/w5SWxk04yzaIHwPdu+d31cxD//Cf/njpfEJ0DGsTrnWpArl6OpB37QG4ju4
dD4bRkEYrdYNWsyRju2HK+865ZblpOR05LPDTUnvTeE6gOd3xxFJKTQEVJpa6Zao
fAFXSuvpt59uuP2jCZX/7mwD+jornVC0hM0SI9pe+fYPBNuz4lc/+xo/0J022L1A
4ZsdBSq7C1p8EQAgWAWhTjc5dTYlvA/CqfEYD1lTr1cPlxGd+jYOqTsKiAT3fxVv
ACScMCUhyduALBnvGr3JeSrJwEnitSs079CZABEBAAG0IE5pY2sgSG93ZWxsIDxu
bGhvd2VsbEBnbWFpbC5jb20+iQFUBBMBCAA+FiEEHCfnK+h88Y73bfEhMUlsLMD9
SC8FAlvr2AsCGwMFCQPCZwAFCwkIBwIGFQoJCAsCBBYCAwECHgECF4AACgkQMUls
LMD9SC8XBwf8CtD5khIAIUA8EVXSZI/TJJUTTwYDg5t79hQZumnAvo20O8MPCIuv
EeBaFSalpvYIGR7sSKtyfyK286N1EjH6qnVb5I4vnFugR5ASrVoTG5c603uFPcf7
XOGEgs/Zbc4X9A1o2vqQeOt40Qp5rWP5zb9cUHIlslk68PMfv4EWOQPKdHoxysqb
6SWwTGkQbbkHGzoaTLXSC4hUSDlTJMC1L+J5+W++wdUj6rcEKIyYAMjUjFMoAaBq
CMZckI7VIMtanbky+EP7M3wWu51iLcdl9911cKCMLAIsoyphRgOjD8JEKY2I2Z2K
TSBlUAdFw4YmkVyq0Uw05TmWXhB5d3rjbrkBDQRb69gLAQgAxy/8KUALAEaXrLk4
X1iNX+9nOC2Bf2SyVP7t/GLO4HhYcDabO6o3qzYTtP0RmTqOok9UY4q0Bb1qBmvI
tUfcU8ijoS1egux23o2QQjaNudzd7L8psYZ7MZn08I48badBP9w5OWcA9KUPnQI7
GTTo8Hc8mkiHf4qa2HmEMXCWJdoQpjsR4+fEv5g+3Mcn7jTPydanx3my4FqKCg0c
u3B1CA7TP2rU+RCBffwvPwZQim3TmXA7VopDcPioiycsM+dKaKmgOsV+Zd/hplmK
Q/TYMhp3WQ36dvNhgZ4NgXEzgZgnmaKme2+XneiUFbRXRAxlTzBIa1Kcm8o1f0xD
Dl7A1QARAQABiQE8BBgBCAAmFiEEHCfnK+h88Y73bfEhMUlsLMD9SC8FAlvr2AsC
GwwFCQPCZwAACgkQMUlsLMD9SC930gf/cIJaOUS/rDlBDohMXWcPW/WrG3bLnDKi
5VUkbMBR6uz7c3SXERp/xd5tBHYzTfLWn3r4TVEmlmo5tyWhkG/K+MWJMVm5BO1P
GAxSYYL0z8RxvwrZs6SJHs3TIzQicjJDuMXQglJu/aaUPQt4j85iH062Oye5zO5L
vydT5+FNerdQQpJ3lPPAjAKDXSNSUUPqp8By1bM4yOmk/F16VMhMKNQc5ijcuuaw
dlO4iIkV+NThFdIiIZ5A0EYnKgftLXSFC9u/BHAMfOIuDDM89FJN43ZzCIMtM5R1
aTxeSQdi0a0QDnccajR1oX+TgvafSd80u7dAwnFetkMNCLcP6kWmVA==
=S+dY
-----END PGP PUBLIC KEY BLOCK-----
The output can be copy-pasted/copied/uploaded/e-mailed, and imported into any compliant PGP software.
You can find other PGP identities on keyservers using gpg --search-keys <search-terms>
where valid search terms are
fingerprints, handles, or parts of the uid attached to the identity.
You can download my identity with
$ gpg --search-keys B86F7896F8768A1A173AA4EDD5A47E58DAFAAF95
You can also read them directly:
$ gpg --import # paste a public key block, e.g. mine:
-----BEGIN PGP PUBLIC KEY BLOCK-----
mDMEW73OzBYJKwYBBAHaRw8BAQdA4DvMXScQ4YghxzAHbPz9kMIoTFg4WNRBCNdy
2uA/+Em0IE5pY2sgSG93ZWxsIDxubGhvd2VsbEBnbWFpbC5jb20+iJAEExYIADgW
IQS4b3iW+HaKGhc6pO3VpH5Y2vqvlQUCW73OzAIbAwULCQgHAgYVCgkICwIEFgID
AQIeAQIXgAAKCRDVpH5Y2vqvlQlvAQCK92HibpdMnQAnzwWQpD3N7bxvAjOAv8yf
6eys2/4T+AEAvdXBU15fiSjLuoH5ZpSTqUTEeUSs+Kevuy92Pa69JgCIuQQQEwoA
HRYhBKWfJjCTy0krRHntrm6FXe5I6KnRBQJb1/3qAAoJEG6FXe5I6KnRdlECCQEL
YgXYnLbdOtmfNnCBcXBESR8rW2P8OAk+rfmxbI6VDKM+ZHSnKJ9KoPSm0YYyJTv5
4/n1zqENnVoBVXNFqHw2kAIJATwk7+e5Wte45cwXfapwUxvxUWO9lDIvBno+RSRe
zJZRYpteGOvnC1LAnPmDmkh882Aua0K6bGB5xv5rtW5cqo65uQENBFu9zswBCAC8
UH2iRAUQ1hRALhEKLsLXB/3O/QSECWBMCUd4/dN0dINrrMuTm6GH0Vyc5c4VgDD9
sGjvUoIf1ecN8433hYxkEtC3goN9AgD6ctkYsYojK4jRLrdhCOgGEE9raXDLkihz
+7MQDoQc75XXLpnAoILGoiV8/Z66GgeDi8eUDy3zzW3Xr+L+KjA73oq+AUMMmeZr
zksRFiXlhVfQA3el9J9dHKGOUG1ATTMTM9GVHErFtmajheodZgqELkyCd0WiSEGw
UhS5y6+cjgCdkMCvHAcXaZWR/gIkTtZXJXVymcxxiE+01vnBCWvt2OM1zDwI8NCa
Hw2KgWQkuz340SSz428fABEBAAGIeAQYFggAIBYhBLhveJb4dooaFzqk7dWkflja
+q+VBQJbvc7MAhsgAAoJENWkflja+q+VwsIA/A6nbSwjRcMxcr9lmIJixMzryhQE
2ShdECZoNiRGhdnQAP9pWk5X562Qlp9XPrcTwGxKFFc+1JYHQ3fwDY4pWvQGBLg4
BFu9zswSCisGAQQBl1UBBQEBB0D9k4JAo0ofntSQyfeJJxGGMkA3uqPzndxbOje5
/N0magMBCAeIeAQYFggAIBYhBLhveJb4dooaFzqk7dWkflja+q+VBQJbvc7MAhsM
AAoJENWkflja+q+VAZQA/3Q4hRv0c8sLk8bzl/9qbko3BxNhnEma67WaTTyEcomk
AQDS7Gbs7InpYKHMIeYtpcIkxAvfh0C6w5xHz1Nu/PfACw==
=uLQW
-----END PGP PUBLIC KEY BLOCK-----
^D
gpg: key D5A47E58DAFAAF95: 1 signature not checked due to a missing
key
gpg: key D5A47E58DAFAAF95: public key "Nick Howell
<nlhowell@gmail.com>" imported
gpg: Total number processed: 1
gpg: imported: 1
gpg: marginals needed: 3 completes needed: 1 trust model: pgp
gpg: depth: 0 valid: 1 signed: 0 trust: 0-, 0q, 0n, 0m, 0f, 1u
gpg: next trustdb check due at 2020-11-13
A list of PGP identities known to gpg
can be found with
$ gpg --list-keys
pub rsa2048 2018-11-14 [SC] [expires: 2020-11-13]
1C27E72BE87CF18EF76DF12131496C2CC0FD482F
uid [ultimate] Nick Howell <nlhowell@gmail.com>
sub rsa2048 2018-11-14 [E] [expires: 2020-11-13]
pub ed25519 2018-10-10 [SC]
B86F7896F8768A1A173AA4EDD5A47E58DAFAAF95
uid [ unknown] Nick Howell <nlhowell@gmail.com>
sub rsa2048 2018-10-10 [A]
sub cv25519 2018-10-10 [E]
The interesting output here is the decoration of the uids:
pub rsa2048 2018-11-14 [SC] [expires: 2020-11-13]
1C27E72BE87CF18EF76DF12131496C2CC0FD482F
uid [ultimate] Nick Howell <nlhowell@gmail.com>
^^^^^^^^^^
<snip>
pub ed25519 2018-10-10 [SC]
B86F7896F8768A1A173AA4EDD5A47E58DAFAAF95
uid [ unknown] Nick Howell <nlhowell@gmail.com>
^^^^^^^^^^
<snip>
For each user id of each PGP identity, gpg
evaluates the level of
validity of the PGP identity for the user id. "Ultimate" validity is
typically reserved for PGP identities you control, i.e., for which
you have the private master key.
Read below for how certifications are produced, and how certifications and "trust levels" are used to determine other levels of validity.
You can create a signed message using gpg --armor --sign
. This
prints a signed message (as defined in the PGP specification); the two
blocks are the original message M
and the corresponding signature
created using a signing keypair RSA(signkey.S, H(M))
. Note the hash
used is included in the message header.
$ gpg --armor --clearsign
Hello
^D
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA256
Hello
-----BEGIN PGP SIGNATURE-----
iQEzBAEBCAAdFiEEHCfnK+h88Y73bfEhMUlsLMD9SC8FAlvr77cACgkQMUlsLMD9
SC8mawf9GCw8b2y0HOOhSGcZhniHJQHgXiRYNTyjSaX5Pv7IqJRaltJM6N3HVFf5
s2xn+sS+DhebiTqLziL3ypmNfWIqVubLqTagOs435HYX8ERfyygXNxA6udRFzb+q
9r0Dp9Q8l8/KPnAr1KEKQZ7Y5b4RL6j3oIuha0tePX8qp8v2h5u0PirRSG/qN5pY
t3XyuUETP3JmjPV/w1H2z5RewqMtf5W05yiZvFm2oG9wdjeBq07Nxe65AlZacbYv
lM5HkY8AmrSjukVF5KyfnwGhYhyLuKtuYcAerxofyEjdBDTNi22K+gIQeoQhR7wt
LNR5MbdYH5uhxiAitit2KnnDis1dwA==
=Di92
-----END PGP SIGNATURE-----
Anyone with your PGP identity can verify that message; paste it into
gpg --verify
and gpg
will compare RSA(signkey.P, signature)
with
H(M)
.
$ gpg --verify
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA256
Hello
-----BEGIN PGP SIGNATURE-----
iQEzBAEBCAAdFiEEHCfnK+h88Y73bfEhMUlsLMD9SC8FAlvr77cACgkQMUlsLMD9
SC8mawf9GCw8b2y0HOOhSGcZhniHJQHgXiRYNTyjSaX5Pv7IqJRaltJM6N3HVFf5
s2xn+sS+DhebiTqLziL3ypmNfWIqVubLqTagOs435HYX8ERfyygXNxA6udRFzb+q
9r0Dp9Q8l8/KPnAr1KEKQZ7Y5b4RL6j3oIuha0tePX8qp8v2h5u0PirRSG/qN5pY
t3XyuUETP3JmjPV/w1H2z5RewqMtf5W05yiZvFm2oG9wdjeBq07Nxe65AlZacbYv
lM5HkY8AmrSjukVF5KyfnwGhYhyLuKtuYcAerxofyEjdBDTNi22K+gIQeoQhR7wt
LNR5MbdYH5uhxiAitit2KnnDis1dwA==
=Di92
-----END PGP SIGNATURE-----
gpg: Signature made Wed 14 Nov 2018 12:49:43 PM MSK
gpg: using RSA key
1C27E72BE87CF18EF76DF12131496C2CC0FD482F
gpg: Good signature from "Nick Howell <nlhowell@gmail.com>" [ultimate]
Anybody with your key can now encrypt a message to you using gpg --armor --recipient $HANDLE --encrypt
; $HANDLE can be a PGP identity
handle, fingerprint, or part of uid (e-mail or name).
This uses the encryption public key of the recipient PGP id to compute
encM = RSA(enckey.P, M)
.
$ gpg --armor --recipient c0fd482f --encrypt
Hello
-----BEGIN PGP MESSAGE-----
hQEMA2S2sG7AbkxzAQf+ObRvB7CwN02RMXZqb3nNV+Pw3zjh1Y+8LFSl0IjFly+M
xAj4Qp3Qk4u26mbn2e1FKNrlVkP2P2dynJPYC5dxWcuHAab3KwKBnooWiHeRf1Tn
UdEi4nTkQxgN10r+fK8gjlGu4LLV7aWt5oYokcBLnbr60qhCDfLtL5N5qtjulzmV
ORCWhVVZTP4ZDZMrpm9yZ3jZzzvEmLKJ5GNKLQP4uWfxBh6Hx9wMMHNdfM5ZR6CK
GtrZ8xoErWyh3Mx9iuMT+wUs+iTVdo2L8FKOM1ueXCJyKR/JAF/VWERhbvC6wvcu
HzMQ+kWBRkZs+Dg2qNlHin/lGmRqHd1tfiu6lWA9xdJBAUgFSimvfLu5UDrn6irQ
82FAYcuCjgvEHLSTiOxz1LBVw0/QrG5dknr75fNmwWRZf+cN01GUq7YT+ie+WfL6
TQs=
=Ln2j
-----END PGP MESSAGE-----
To decrypt, paste the PGP message into gpg --decrypt
; gpg
will
compute RSA(enckey.S, encM)
.
$ gpg --decrypt
-----BEGIN PGP MESSAGE-----
hQEMA2S2sG7AbkxzAQf+ObRvB7CwN02RMXZqb3nNV+Pw3zjh1Y+8LFSl0IjFly+M
xAj4Qp3Qk4u26mbn2e1FKNrlVkP2P2dynJPYC5dxWcuHAab3KwKBnooWiHeRf1Tn
UdEi4nTkQxgN10r+fK8gjlGu4LLV7aWt5oYokcBLnbr60qhCDfLtL5N5qtjulzmV
ORCWhVVZTP4ZDZMrpm9yZ3jZzzvEmLKJ5GNKLQP4uWfxBh6Hx9wMMHNdfM5ZR6CK
GtrZ8xoErWyh3Mx9iuMT+wUs+iTVdo2L8FKOM1ueXCJyKR/JAF/VWERhbvC6wvcu
HzMQ+kWBRkZs+Dg2qNlHin/lGmRqHd1tfiu6lWA9xdJBAUgFSimvfLu5UDrn6irQ
82FAYcuCjgvEHLSTiOxz1LBVw0/QrG5dknr75fNmwWRZf+cN01GUq7YT+ie+WfL6
TQs=
=Ln2j
-----END PGP MESSAGE-----
gpg: encrypted with 2048-bit RSA key, ID 64B6B06EC06E4C73, created 2018-11-14
"Nick Howell <nlhowell@gmail.com>"
Hello
The major problem in asymmetric cryptosystems is called validity:
how to trust that you have the correct PGP identity for a given uid;
i.e., if a PGP id claims to have Nick Howell <nlhowell@gmail.com>
as
a uid, is Nick Howell the real owner of the secret keys?
A major strategy in attacking asymmetric cryptosystems is to convince the target to use a public keypair for which the attacker holds the secret part. They can do this by stealing the secret keys, or they can do it by tricking the target into using a public key with a forged identity.
The former problem can be solved by keeping your secret keys secure; this is the purpose of the passphrase, which keeps your secret keys encrypted when your computer is off. In the extreme, security means secret keys are kept on an "energy-gapped" computer, and all decryption and signing occurs there.
A more modest improvement in security is the use of a hardware "cryptotoken" or "smartcard;" this is a small microcontroller which holds your secret keys and lives on a usb stick. Secret keys are not made accessible to the main computer, so malware and hackers will not be able to steal your keys (though they will be able to mess with the data sent to the token).
See Gnuk on Blue Pill for how to make your own cryptotokens from 200₽ microcontrollers.
The latter problem is solved by face-to-face verification.
If Alice and Bob wish to have secure communication, the solution is for them to meet face-to-face and compare the fingerprints of their PGP identities. So that they don't forget the results of this, after comparison they Certify each-others identities. This uses the master keypair to produce a signature of the uid+fingerprint of the identity. (Typically all uids are signed, but in some circumstances you want only to sign one of many uids.)
If Alice and Bob don't know each-other well, they may wish to see some evidence that the uids they are signing are "real" in some sense: common practices involve
To certify a key with gpg
, you use the gpg --sign-key
command.
Verify the fingerprints face-to-face and then type y
.
$ gpg --sign-key $HANDLE # handle you want to certify
pub ed25519/D5A47E58DAFAAF95
created: 2018-10-10 expires: never usage: SC
trust: unknown validity: unknown
sub rsa2048/EB5F5719CCBFEE45
created: 2018-10-10 expires: never usage: A
sub cv25519/8244BE89B2B04368
created: 2018-10-10 expires: never usage: E
[ unknown] (1). Nick Howell <nlhowell@gmail.com>
pub ed25519/D5A47E58DAFAAF95
created: 2018-10-10 expires: never usage: SC
trust: unknown validity: unknown
Primary key fingerprint: B86F 7896 F876 8A1A 173A A4ED D5A4 7E58 DAFA AF95
Nick Howell <nlhowell@gmail.com>
Are you sure that you want to sign this key with your
key "Nick Howell <nlhowell@gmail.com>" (31496C2CC0FD482F)
Really sign? (y/N)
Afterwards, gpg --list-keys
will show the key with "full" validity,
instead of "unknown."
You can upload your signature to the keyservers by sending the
target key: gpg --send-keys dafaaf95
.
You can build a graph in which nodes are PGP identities and edges are certifications. If you have some faith in the people you have certified, you might be willing to assign validity to PGP identities which you haven't personally certified, but which others have.
(Nick) -------- (Danya)
/
/
/
(Fran)
This happens in the real world constantly: you choose businesses, doctors, friends, schools, books, all based on the recommendations of others.
In PGP, a trusted identity is one which you trust to make valid
certifications; any identity which is certified by a trusted identity
X
is valid for your identity. A marginally trusted identity is one
which you partly trust to make valid certifications; if enough
marginally trusted identities have certified an identity X
, then you
consider X
as valid.
Here, Fran's PGP id has assigned my PGP id full trust; since I have certified Danya's PGP id, Fran's also considers Danya's to have full validity.
cert
(Nick) --------- (Danya)
trust / .
cert / .
/ . valid (no cert)
(Fran)
(note that technically these edges should be directed; it is possible for such relationships to be asymmetric)
To assign trust with gpg --edit-key $HANDLE
, use the trust
command. In the default configuration:
$ gpg --edit-key $HANDLE
gpg (GnuPG) 2.2.10; Copyright (C) 2018 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.
pub ed25519/D5A47E58DAFAAF95
created: 2018-10-10 expires: never usage: SC
trust: unknown validity: unknown
sub rsa2048/EB5F5719CCBFEE45
created: 2018-10-10 expires: never usage: A
sub cv25519/8244BE89B2B04368
created: 2018-10-10 expires: never usage: E
[ unknown] (1). Nick Howell <nlhowell@gmail.com>
gpg> trust
pub ed25519/D5A47E58DAFAAF95
created: 2018-10-10 expires: never usage: SC
trust: unknown validity: unknown
sub rsa2048/EB5F5719CCBFEE45
created: 2018-10-10 expires: never usage: A
sub cv25519/8244BE89B2B04368
created: 2018-10-10 expires: never usage: E
[ unknown] (1). Nick Howell <nlhowell@gmail.com>
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?