Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Document PGP, RAM Disks, and Symmetric Encryption #107

Open
wants to merge 24 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions tooling/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,9 @@ Cheat sheets, links, procedures, and reference documents related to external too
### Index
- [Computer Setup](./computer-setup.md) - options for keeping your work and personal life separate on your computer.
- [Docker](./docker.md) - docker reference and quick-start guide.
- [Encryption](./encryption.md) - techniques for securely working with sensitive data on Linux.
- [PGP](./encryption.md#asymmetric-encryption) - securely share secrets.
- [Symmetric Encryption](./encryption.md#symmetric-encryption) - securely store secrets.
- [RAMdisk](./ramdisk.md) - work with files in memory for speed or privacy.
- [Tool Install Guide](./tool-install-guide.md) - install common tooling on your machine.
- [Ubuntu Virtual Machine Setup Guide](./vm-setup.md) - setup an Ubuntu virtual machine you can use for testing, and quickly restore to known-good states.
Empty file modified tooling/docker.md
100755 → 100644
Empty file.
225 changes: 225 additions & 0 deletions tooling/encryption.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,225 @@
# Encryption
Various techniques for securely working with sensitive data on Linux.

<!-- contents box begin -->
<table>
<tr/>
<tr>
<td>
<p/>
<div align="center">
<b>Contents</b>
</div>
<p/>
<!-- contents markdown begin -->

1. [Asymmetric Encryption](#asymmetric-encryption)
1. [Create a PGP Key Pair](#create-a-pgp-key-pair)
1. [View Your Key Pair](#view-your-key-pair)
1. [Share Your Public Key](#share-your-public-key)
1. [Import a Public Key](#import-a-public-key)
1. [Encrypt a Message](#encrypt-a-message)
1. [Decrypt a Message](#decrypt-a-message)
1. [Symmetric Encryption](#symmetric-encryption)
1. [Encrypt](#encrypt)
1. [Decrypt](#decrypt)
1. [See Also](#see-also)

<!-- contents markdown end -->
<p/>
</td>
</tr>
</table>
<!-- contents box end -->

## Asymmetric Encryption
Asymmetric encryption uses a pair of keys to encrypt and decrypt data, a public key that can be shared with anyone and a private key that needs to be kept secret. The public key is used to encrypt secret data, resulting in cyphertext that can be sent over the Internet. The recipient uses their private key to decrypt it. This is useful for securely sharing data with others.

To securely share secrets with others, for example to send service account credentials with a colleague on your team who does not use a [password manager](https://bitwarden.com), you can use PGP.

### Create a PGP Key Pair
Before you can send or receive PGP messages, you need to create a key pair. You can do this with [GnuPG](https://gnupg.org).
1. Install `gpg` if you don't already have it.
- On Debian-family Linux:
```bash
sudo apt-get install -y gpg
```
- On macOS, you can install it using [Homebrew](https://brew.sh):
```bash
brew install gnupg
```
- On Windows, you can install it using [Chocolatey](https://chocolatey.org):
```powershell
choco install gpg
```
1. Use your [password manager](https://bitwarden.com) to generate a strong, unique passphrase for your key pair. You will need this passphrase to decrypt messages.
1. Generate a new key pair.
> When you run this next command, it will ask you for a passphrase to protect your key...and you will not be able to click outside the dialogue box. So, if you use a password manager, copy your passphrase to your clipboard before running this command.
```bash
gpg --batch --gen-key <<TXT
Key-Type: RSA
Key-Length: 4096
Subkey-Type: RSA
Subkey-Length: 4096
Name-Real: Bill Gates
Name-Email: [email protected]
Expire-Date: 2024-10-01
TXT
```
If that command doesn't work for you then you can generate a key pair manually by answering some questions. Pick either "RSA and RSA" and use a key length of at least 2048 bits, or pick "ECC and ECC" and use `ed25519` or any `NSIT` curve with a key length of at least 256 bits.
```bash
gpg --full-generate-key
```
On the last step, be sure to press `o` for "okay" to generate the key pair.

### View Your Key Pair
You can see what key pairs you have on your computer using this command.
```bash
gpg --list-keys
```

### Share Your Public Key
You need to share your public key to receive encrypted messages. This command will print it out:
```bash
gpg --armor --export [email protected]
```
You can then copy and paste the output into an email or IM, including the `-----BEGIN PGP PUBLIC KEY BLOCK-----` and `-----END PGP PUBLIC KEY BLOCK-----` lines. Alternatively, you can save it to a file and attach that to your message.
```bash
gpg --armor --export [email protected] > public-key.asc
```

### Import a Public Key
If someone sends you their public key, you can import it using this command:
```bash
gpg --import public-key.asc
```
Or, if you are copying and pasting it from an email or IM, you can do this:
```bash
gpg --import <<TXT
```
Then paste the key block, and finish with:
```bash
TXT
```
You will see their name, email, and key here:
```bash
gpg --list-keys
```

### Encrypt a Message
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A couple other useful tips for basic encryption that aren't mentioned in here:

  1. It's possible to encrypt a single message to multiple recipients.
  2. It's possible to sign and encrypt at the same time, to provide some authenticity on where the encrypted message came from.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Both added, with signing now being the default in my examples as it is good practice.

You can sign and encrypt a message to someone's public key. This command will encrypt a file:
```bash
gpg --encrypt --sign --recipient [email protected] message.txt
```
This will create a new file in the current directory called `message.txt.gpg` which you can send to the recipient.

> [!TIP]
> Signing your PGP message enables the recipient to verify that it came from you and was not tampered with. This is good practice, but it is not strictly necessary. Just leave off `--sign` if you don't want to sign the message.
> ```bash
> gpg --encrypt --recipient [email protected] message.txt
> ```
> This will leave the same encrypted `message.txt.gpg` file in the current directory, just without your signature embedded.

You can sign and encrypt a message to two or more recipients. Just add them in there!
```bash
gpg --encrypt --sign --recipient [email protected] --recipient [email protected] message.txt
```
You will get the same `message.txt.gpg` file in the current directory, but both recipients will be able to decrypt it.

You can encrypt any file, not just text, such as an archive.
```bash
gpg --encrypt --sign --recipient [email protected] archive.tar.gz
```
This would create `archive.tar.gz.gpg`. You can change the name of the output file if you want.
```bash
gpg --encrypt --sign --recipient [email protected] --output cyphertext.tar.gz.gpg cleartext.tar.gz
```
This would create `cyphertext.tar.gz.gpg`.

You can also encrypt text directly:
```bash
echo 'Hello, World!' | gpg --encrypt --armor --recipient [email protected]
```
This will print out the encrypted message, which you can copy and paste into an email or IM.

When you are done, you can securely delete your secrets with `shred`...
```bash
shred -uvz example.txt
```
...or `wipe`...
```bash
wipe -fr example-dir
```
...if you want. You may need to install them.

### Decrypt a Message
If someone sends you a PGP message, you can decrypt it using your private key and passphrase.

> [!TIP]
> When you run any of these commands, it will ask you for your passphrase to decrypt the message...and you will not be able to click outside the dialogue box. So, if you use a password manager, copy your passphrase to your clipboard before pressing `Enter` on any of these commands.

To decrypt a file, you always need to specify the output file unless you want it to print to your terminal.
```bash
gpg --output message.txt --decrypt message.txt.gpg
```
Decrypt an archive:
```bash
gpg --output archive.tar.gz --decrypt archive.tar.gz.gpg
```
These will leave the file in the current directory.

To decrypt text directly:
```bash
echo '-----BEGIN PGP MESSAGE-----' | gpg --decrypt
```
This will print out the message in your terminal.

## Symmetric Encryption
Symmetric encryption uses the same key to encrypt and decrypt data. This is useful for encrypting data at rest, such as a backup file or a database dump.

> [!TIP]
> For particularly sensitive documents, you may wish to work with them in a [RAMdisk](./ramdisk.md) to avoid writing them to disk at all.

### Encrypt
You can compress and encrypt a file using a symmetric key like this:
```bash
gpg --quiet --symmetric --cipher-algo AES256 --s2k-digest-algo SHA512 --s2k-mode 3 --s2k-count 65011712 --compression bzip2 --bzip2-compress-level 9 example.txt
```
This will leave a file called `example.txt.gpg` in the current directory.

You can encrypt an archive like this. We will leave off the compression this time.
```bash
gpg --quiet --symmetric --cipher-algo AES256 --s2k-digest-algo SHA512 --s2k-mode 3 --s2k-count 65011712 example.tar.gz
```
The output file would be `example.tar.gz.gpg`.

When you are done, you can securely delete your secrets with `shred`...
```bash
shred -uvz example.txt
```
...or `wipe`...
```bash
wipe -fr example-dir
```
...if you want. You may need to install them.

### Decrypt
Decryption is trivial with `gpg`.
```bash
gpg --output example.tar.gz --decrypt example.tar.gz.gpg
```
You don't have to specify the cipher or digest algorithms, or the compression level, because `gpg` will figure that out from the encrypted file.

## See Also
Internal resources.
- [./Tooling](./README.md) ⤴
- [../Engineering](../README.md) ⤴⤴
- [RAMdisk](./ramdisk.md) - work with files in memory for speed or privacy.

External resources.
- [Bitwarden](https://bitwarden.com) - password manager
- [GnuPG](https://gnupg.org) - the GNU Privacy Guard encryption, decryption, and signing tool

---
> **_Legal Notice_**
> This document was created in collaboration with a large language model, machine learning algorithm, or weak artificial intelligence (AI). This notice is required in some countries.
81 changes: 81 additions & 0 deletions tooling/ramdisk.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
# RAMdisk
You can mount some of your computer's memory to your filesystem in order to perform read/write intensive tasks very, very quickly such as processing large JSON files, or to [work with sensitive documents](./encryption.md) that you don't want to risk writing to disk. This is called a RAM disk.

<!-- contents box begin -->
<table>
<tr/>
<tr>
<td>
<p/>
<div align="center">
<b>Contents</b>
</div>
<p/>
<!-- contents markdown begin -->

1. [Preparation](#preparation)
1. [Creation](#creation)
1. [Destruction](#destruction)
1. [See Also](#see-also)

<!-- contents markdown end -->
<p/>
</td>
</tr>
</table>
<!-- contents box end -->

## Preparation
Make a folder to mount the RAM disk to.
```bash
sudo mkdir -p /mnt/ram
```
Take ownership of that folder.
```bash
sudo chown "$USER:$USER" /mnt/ram
```
Put a file there so you can tell whether or not a RAM disk is mounted.
```bash
echo 'WARNING: If you can see this, there is currently no RAM disk mounted!' > /mnt/ram/STOP.txt
```
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Alternatively what I like to do is remove permissions from the empty directory that will be the mount point. That will prevent reading or writing or even looking in to the directory until something is mounted there

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But then how do you know the mount point exists?

Can you please provide an example, if you want me to add it?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You don't need to add it.

Basically something like

sudo mkdir /mnt/ram
sudo chmod 0600 /mnt/ram

Now it's impossible (non-root) to ls /mnt/ram or touch /mnt/ram/foobar. So you can't accidentally use it when there is nothing mounted there. But it's still possible to mount something at /mnt/ram.


Optionally, install `wipe` if you want to delete the contents of your RAM disk immediately instead of waiting for the system to overwrite it.
```bash
sudo apt-get update
sudo apt-get install -y wipe
```

## Creation
Mount a 16 GB RAM disk.
```bash
sudo mount -o size=16G -t tmpfs none /mnt/ram
```
Verify your `STOP.txt` file is gone.
```bash
ls -la /mnt/ram
```
Now you can work there.

## Destruction
Optionally, you can overwrite the contents of your RAM disk immediately instead of waiting on your system to do it after unmounting.
```bash
wipe -fr /mnt/ram/*
```
Unmount the RAM disk.
```bash
sudo umount /mnt/ram
```
Verify your `STOP.txt` file is back.
```bash
ls -la /mnt/ram
```

## See Also
Internal resources.
- [./Tooling](./README.md) ⤴
- [../Engineering](../README.md) ⤴⤴
- [Encryption](./encryption.md)

---
> **_Legal Notice_**
> This document was created in collaboration with a large language model, machine learning algorithm, or weak artificial intelligence (AI). This notice is required in some countries.