Organisation: | Copyright (C) 2021-2024 Olivier Boudeville |
---|---|
Contact: | about (dash) howtos (at) esperide (dot) com |
Creation date: | Saturday, November 20, 2021 |
Lastly updated: | Thursday, January 4, 2024 |
A goal here is to favor cryptographic privacy and authentication for data communication.
More precisely:
Now that electronic exchanges are central to most communications, controlling one's e-mail services is of paramount importance.
It is a real pity that most individuals will not be able in practise to run their own mail server (Message transfer agent), short of being able to setup through their Internet provider a proper reverse DNS information (as any e-mail that such a home server would emit would likely be considered as spam/junk mail by the recipients).
So one will have to resort to third-party e-mail services ("MX plan"). We do not see the reliance on one's Internet provider e-mail solution as a good choice (even if being able to make use of such an address regardless of any active subscription to that provider), possibly not all registrars are also good email hosters, and surely we do not want to depend on any GAFAM-related service.
The last remaining solution is therefore to elect a dedicated provider of e-mail hosting, which most of the time incurs monthly fees, albeit rather low (e.g. 1 euro per month).
In that case we strongly recommend:
Wanting to test whether your current e-mail system is reliable? We recommend using the MECSA online testing tool, which is provided by the European Commission and allows to learn a lot about the level of security reached by one's email system.
Albeit such a securing scheme may apply to at least most of the digital exchanges, in practice it is mainly used in the context of email security.
In the general case, sending an email will end up having its content stored at least on:
Possibly with intermediate organisations between the endpoint ones, possibly stored on several locations per organisation - possibly times the number of specified recipients.
Moreover many countries require by law that emails are stored by Internet providers durably (often at least for one year) - not to mention the large-scale data harvesting that many countries perform, officially or not, with their own measures, on their own territory or on the one of others.
That's a rather large number of copies for one's private correspondence - to the point that emails sent in clear text could be mostly considered as public. Not to mention that they could also be altered in the process, at some point(s) in the chain.
Common solutions exist to ensure that a given mailserver is indeed in charge of a given domain name (SPF), that a given email originates from a given mailserver and has not been tampered with (DKIM) and that any non-conformance can be managed according to a policy recommended by the emitter (DMARC), but none is about the privacy of your messages.
Encrypting and signing are solutions to restore some privacy and safety - yours, but also the ones of the persons with whom you happen to correspond.
It is currently best done thanks to the OpenPGP open standard for encrypting, signing and decrypting data and communications.
GnuPG (GNU Privacy Guard) is a complete and free implementation of it (we suppose here that at least its 2.2.* version is used).
The corresponding command-line executable, gpg, can be installed on Arch Linux with: pacman -Sy gnupg.
A first step is to generate locally one's key pair, knowing that each public key is bound to a username or an e-mail address (which is our preference; having one's domain name allows to create any number of them).
A nice feature of this cryptographic scheme is that one may issue any number of keys in full autonomy and with neither consequences nor cost. So as many key pairs as notions of "unrelated identities" may be freely created.
Several settings can be chosen when generating a key, and logically the strongest keys are preferred. Yet uncommon/too recent generation algorithms and/or higher key lengths may not be supported by the various tools [1], so applying the default settings retained by gpg, or similar ones yet a bit stronger (e.g. at the time of this writing, November 2021, RSA 4096 bits rather than 3072 bits) is probably the way to go (it can already be deemed safe, and will be widely supported); so the generation may be best triggered simply thanks to:
# For current defaults: $ gpg --gen-key # Or, for more control: $ gpg --full-gen-key
[1] | With "cutting-edge" settings, some tools (like Thunderbird) on your side and/or the email clients of your recipients may be unable to make use of the resulting keys, and may fail to report clearly that they actually do not support this algorithm or its parametrisation. So one may consider sticking to reasonable gpg defaults, or use paranoid settings only for a fully-private primary key whence actual work keys are derived. |
If preferring rather paranoid settings, presumably for an extra security/durability, one can select ECC (for Elliptic-curve cryptography), with the Sign, Certify and Authenticate capabilities enabled (even if authentification is not used by many common protocols), and opt for the Brainpool P-512 curve through:
$ gpg --full-gen-key --expert
In all cases, one may enter 1y to set the initial validity duration of the generated key to one year, and already plan in one's agenda, a dozen days before the end of its validity, its renewal.
Then one may enter one's selected identity (e.g. for Real name, one may enter James Bond), one's email address of interest (e.g. james.bond@mi6.org) and possibly:
The requested passphrase only consists on a last-resort protection of the generated private key (that you should never transmit to anyone), in order to avoid that anyone accessing this file on your computer becomes directly able to fully impersonate this identity.
The operation generates a public/private key pair, and also an associated emergency revocation certificate, so that you can invalidate it at any time and for any reason:
gpg: key 9A60ADA4E151B8B5 marked as ultimately trusted gpg: directory '/home/james/.gnupg/openpgp-revocs.d' created gpg: revocation certificate stored as '/home/james/.gnupg/openpgp-revocs.d/C3987680AD9B79FDC6B7D25C9D60ADA5E115A8B5.rev' public and secret key created and signed. pub brainpoolP512r1 2021-11-26 [SCA] [expires: 2022-11-26] C3987680AD9B79FDC6B7D25C9D60ADA5E115A8B5 uid James Bond <james.bond@mi6.org>
Here C3987680AD9B79FDC6B7D25C9D60ADA5E115A8B5 is the full fingerprint of the public key; it could be shortened to its 8, if not 4, last characters (long/short ID), yet it would expose to the forging of intentionally-colliding keys, so one should only designate a key based on its full fingerprint, and forget unsafe abbreviations.
The public key can be freely shared, whereas the private one and the revocation certificate must be equally well protected (preferably in different places).
The only well-known threats to these keys are either a flaw (intentional loophole or accidental weakness) in the cryptographic algorithms on which they rely, or the advent of major research progresses such as quantum computing. Yet it still remains possible for one to "upgrade" one's key with newer algorithms (a new key superseding an older one that is to be revoked afterwards), so as always it will be a never-ending struggle between the spear and the shield, i.e. attack and defense.
As signing and encrypting correspond to different use cases, having different keys for each may make sense. But instead of generating two unrelated keys, one shall create:
These "derived" subkeys are meant to change more frequently, to be able to be revoked independently, and thus are safer to expose in less secure systems.
Use gpg --edit-key and addkey in order to add a subkey to a key, and refer to this section to export the subkey.
See also these very relevant Debian guidelines for further information about subkey management.
The full gpg state is stored by default in its ~/.gnupg/ tree.
One may notably notice in it:
The public keys are usually given a .pub extension [2].
[2] | Other common extensions are .gpg (for encrypted content and also standard signatures), .asc (for clear-text signatures and other ASCII content), and .sig (for detached signatures). |
Even if a backup of one's key pair could be made by creating and encrypting an archive of this gpg filesystem tree, a far better solution is to use its integrated procedure, as the structure of its internal state may change from a version/platform of gpg to another. So the best course of action is to use the following command in order to generate a backup of a key pair in a standard, durable form:
$ gpg -o $(date '+%Y%m%d')-full-key-backup-for-james.bond-at-mi6.org.gpg --export-secret-keys james.bond@mi6.org
This will produce a half-kilobyte file containing the full key pair, whose type is:
20211126-full-key-backup-for-james.bond-at-mi6.org.gpg: OpenPGP Secret Key Version 4, Created Fri Nov 26 21:52:31 2021, ECDSA; User ID; Signature; OpenPGP Certificate
Of course, so that it may be used in the future, this backup of (notably) the private key should not be encrypted with that same key.
Specifying in filenames the email address may be avoided, in the sense that rather than having multiple keys (e.g. as many as email accounts), it is often more convenient to have a single key supporting multiple names/addresses (see the section about subkey below); so:
# If using fingerprints and potentially having multiple registered email # accounts, just focusing on their common identity: # $ gpg -o $(date '+%Y%m%d')-full-key-backup-for-james.bond.gpg --export-secret-keys C3987680AD9B79FDC6B7D25C9D60ADA5E115A8B5
A backup of the revocation certificate shall be done as well (knowing that by design it is not password-protected, and thus having access to this certificate is sufficient to be able to kill your key), preferably in a different location as the role of this certificate is to serve as an urgent safety measure should the private key be lost (non-emergency revocations should be performed thanks to the more adapted and informative --generate-revocation option instead).
For long-term auxiliary storage, such a backup can be printed (on paper), possibly thanks to Paperkey (installed on Arch with pacman -Sy paperkey). For example:
# To print directly: gpg --export-secret-key my_key_fingerprint | paperkey | lpr # To store first (less secure): gpg --export-secret-key my_key_fingerprint | paperkey --output my_key_fingerprint.asc
Such exports are ASCII texts, but they can also take the perhaps more convenient (and maybe less secured if having to trust one's smartphone) form of a QR code:
$ gpg --export-secret-key my_key_fingerprint | paperkey --output-type raw | qrencode --8bit --output my_key_fingerprint.qr.png
Besides key pairs, following backups shall be done:
One may:
Keys are meant to expire, so that they are updated as technology progresses.
To check whether one's (secret) keys expired:
$ gpg --list-secret-keys --keyid-format LONG [...] sec brainpoolP512r1/3D60ADA5E251A8B5 2021-11-26 [SCA] [expired: 2022-11-26] C3987680AD9B79FDC6B7D25C9D60ADA5E115A8B5 uid [ expired] James Bond <james.bond@mi6.org> [...]
So this key expired and shall be renewed; let's extend it of two years, and proceed interactively, based on its KEYID:
$ gpg --edit-key 3D60ADA5E251A8B5 Secret key is available. sec brainpoolP512r1/3D60ADA5E251A8B5 created: 2021-11-26 expired: 2022-11-26 usage: SCA trust: ultimate validity: expired [ expired] (1). James Bond <james.bond@mi6.org> 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) 2y Key expires at Wed 01 Jan 2025 12:40:27 PM CET Is this correct? (y/N) sec brainpoolP512r1/3D60ADA5E251A8B5 created: 2021-11-26 expires: 2025-01-01 usage: SCA trust: ultimate validity: ultimate [ultimate] (1). James Bond <james.bond@mi6.org> gpg> trust gpg> save
Typically if having expired keys not intended to be renewed:
$ gpg --delete-secret-key KEYID
Create a master key that will never leave one's network, thanks to gpg --expert --full-generate-key:
Possibly add other identities (typically email addresses), with gpg --edit-key, adduid, then uid 2, trust, uid 2 (to unselect), primary (for uid 1) and save.
Sign this new key with any past one:
$ gpg --default-key OLDKEYID --edit-key NEWKEYID gpg> sign gpg> save
Define as many of them as needed (based on gpg --expert --edit-key NEWKEYID), possibly one for signing, one for encrypting and one for authenticating (apparently not automatically generated), each time with addkey; select a strong yet commonly-accepted algorithm (e.g. RSA 4096 bits), and a shorter lifespan (e.g. 2 years).
A simpler "triple" use (S/E/A) key may be preferred or additionally created.
Create a revocation certificate for your master key, specifying reason 1 (Key has been compromised) and clarify with a comment (This revocation certificate has been generated at key creation.):
$ gpg --output $(date '+%Y%m%d')-masterkey.gpg-revocation-certificate.key --gen-revoke KEYID
Stores possibly multiple offline copies of that certificate.
Backup secret keys:
$ gpg -o $(date '+%Y%m%d')-full-key-backup-for-james.bond.gpg --export-secret-keys
Dispatch the various public keys generated (for signing, encrypting, authenticating):
$ gpg --send-keys KEYID
Transfer the james-bond.pub public key to webserver (e.g. https://mi6.org/), based on gpg -o james-bond.pub --export PUBKEYID.
As the time of this writing (Tuesday, January 3, 2023), my daily key for signing / encrypting / authenticating is a RSA 4096-bit one designated as 3e090de4d08e42944d195a7bb8235ece469eb77f.
It can be obtained by different means:
The use of key pairs in the absence of a certificate authority directly relates to Decentralized Identifiers (DIDs), a class of universal solutions (not depending on any context/organisation, and able to be recognized by any) with which anyone can create one's (globally unique) identifiers that remain in one's full control: one freely issues them, they remain valid as long as their issuer wishes (as none but their creator itself can revoke them), and (for example unlike mere UUIDs) they can be cryptographically verified by anyone.
No external central authority applies to such identifiers, which cannot reveal personal information unless decided by their issuer and thus sole controller.
In practice, although other solutions could maybe be considered, it involves, like discussed in the previous sections, generating on one's own at least a public/private key pair, to store safely the private one and to share as widely as needed the public one. Then one can sign and/or encrypt one's messages with a pretty good hope that they will remain secure for a while; such a system enables partial disclosure (as one chooses what one encrypts or signs) in full control (as all operations are driven by the private key that the issuer is the only one to control).
These decentralised identifiers, together with the principle of addressing a digital content by its fingerprint (e.g. SHA1), offer a solution bringing many interesting properties and opening new possibilities to distributed systems (e.g. for blockchains, a user account is often identified by the fingerprint of its associated public certificate).