# using pgp in direct messages

Here is a quick guide on how to drive pgp manually on the command-line so you can encrypt messages on any platform where you can post text or images.

This approach makes some practical trade-offs. You're still somewhat susceptable to replay attacks, for example (although if you're using signatures, you will see the timestamp which helps with that). And admins still know who is talking to who, and that they are using encryption. Still, it's much better than nothing.

No security scheme is perfect. Don't write down your criminal activity on a computer.

You will need:

This post will use `xclip` but don't worry if you don't have it, you can do everything by copying and pasting a bit more manually. Or mac has a similar command, `pbcopy` and windows has `clip`.

For all of these steps, substitute appropriate values for YOURNAME, YOU@YOUR_EMAIL, and YOURFRIEND.

# creating pgp keys

First, generate a primary ed25519 key (this will be used to generate sub-keys):

gpg --quick-generate-key 'YOURNAME <YOU@YOUR_EMAIL>' ed25519 cert never

Now create a signing key and an encryption key.

To create keys with no password:

fp=$(gpg --list-options show-only-fpr-mbox --list-secret-keys | awk '{print $1}'); \
  gpg --batch --passphrase '' --quick-add-key $fp ed25519 sign 0 \
  && gpg --batch --passphrase '' --quick-add-key $fp cv25519 encrypt 0

Or to create create keys and be prompted for a password:

fp=$(gpg --list-options show-only-fpr-mbox --list-secret-keys | awk '{print $1}'); \
  gpg --batch --quick-add-key $fp ed25519 sign 0 \
  && gpg --batch --quick-add-key $fp cv25519 encrypt 0

# importing and exporting keys

Now each side of the connection needs to exchange public keys.

To get your own key and copy to your clipboard:

gpg --armor --export YOURNAME | xclip

Send this to your friend somehow or upload it to your website if you have one. It's safe to share this info publicly, so long as you don't mind that people might know you're using encryption.

The public key messages might be a bit long for the messenger you're using if that's how you're exchanging public keys. Check the long messages section for tips.

Copy the public key from your friend into your clipboard, then do:

xclip -o | gpg --import

Or if your friend uploaded their key to a website you can do:

curl https://yourfriends.website/theirkey.pgp | gpg --import

Once you've both imported each other's keys, you can exchange messages.

# exchanging messages

During the import step, you should have seen something like:

gpg: key DAA459DC57723A49: public key "synthia <sy@nthia.dev>" imported

In that example, you could refer to the key as "synthia" or "sy@nthia.dev".

If you missed that message during import, you can check the output of this command for something similar:

$ gpg --list-public

## encrypt

Once you have the name for YOURFRIEND (either the common name part or the email part) from that key, you can encrypt a message and copy it to your clipboard. When the encrypted message is in your clipboard you can paste it into whichever messenging service you're using.

echo 'hiiiiiiii' | gpg -aser YOURFRIEND | xclip

Or you can type out your message (press CTRL+d when you're done typing):

gpg -aser YOURFRIEND | xclip

Or you could import your message from a text file:

<somefile.txt gpg -aser YOURFRIEND | xclip

If the contents are too long to send in a single message in the app you're using, check out long messages section for tips.

## decrypt

When you receive a message from a friend, it should look something like this:

-----BEGIN PGP MESSAGE-----

hF4DCJiXJXsuOcsSAQdAfitiPD07t28z43Q6Vf+bNABHWc4K/dh+/BffYIyVdTYw
izy+QY7RAC9gp630BtADzTDL+mkI8qr01o8gNYKL2vKCE1hz0BNOhDOA+/Jyzs4y
1MAaAQkCEDADdlTvKFgBQh9GzLMwtGJXk3iwWUcapu899XdpjegDWswSgCLitSMW
qeVZ686jb8Tdft9p5JTiizwpkvRwwEkuUltPOL1AWgILrqK0Rt5E+RVnQw3xeRjV
DcbMMzxsIDHbZjXX2jRj9ldFaMEyoBysTWayLq03hmcV0t2NjBTmQrgz/ymrbS2t
Li7pfSx183XRP8XGrswvn78RkuAFrH/31XwVkygN9pPQfKH+8YAlQG4MKcUOKpjk
xFIr67sNn6bQWO55FJO9kLCaxaYQ08ICZYZ85XY=
=tavF
-----END PGP MESSAGE-----

Copy the whole thing (including the lines beginning with dashes) to your clipboard, then do:

xclip -o | gpg -d

You might be prompted to type in your passphrase, if you set one.

If everything worked, you should see the message contents and then below that, something like:

gpg: Signature made Sat Nov 19 09:12:03 2022 UTC
gpg:                using EDDSA key 4A12DAEE11E0E0E9B9BBDC828D6478BBF3CE92AB
gpg:                issuer "sy@nthia.dev"
gpg: Good signature from "synthia <sy@nthia.dev>" [ultimate]

## trust

When you encrypt a message to your friend, you will see an annoying prompt:

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
Or when you decrypt a message from your friend, you will see a warning:
gpg: WARNING: This key is not certified with a trusted signature!
gpg:          There is no indication that the signature belongs to the owner.

To make these warnings and prompts go away:

gpg --edit-key YOURFRIEND trust quit

Then you will see this prompt:

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? 

Type "5" and press enter. Then you will be asked:

Do you really want to set this key to ultimate trust? (y/N)

Type "y", press enter.

Now when you encrypt or decrypt messages with your friend, you will no longer see warnings or prompts about trust.

# long messages

If you hit a character limit because some of the gpg messages are too big, there are a few things you can try.

## split up messages

Send everything you can up to the character limit, then send the rest in one or more additional messages. Your friend will need to know to piece them back together on the other side. Make sure you don't miss or duplicate a character or the decryption will fail.

## qr-codes

If the messenging platform you're using supports images, then you can convert the pgp messages to qr codes.

You and your friend will each need some tools for encoding and decoding:

sudo apt install qrencode zbar-tools

Now you can encrypt a message and write the ciphertext to an image file:

echo 'hi this is the message' | gpg -aesr YOURFRIEND | qrencode -o msg.png

Send msg.png to your friend. Then your friend can do:

zbarimg -q --raw msg.png | gpg -d

If that worked, you should see something like:

hi this is the message
gpg: Signature made Sat Nov 19 10:45:32 2022 UTC
gpg:                using EDDSA key E8A139691B87A7DF1AE81FAC47D50726EA442947
gpg:                issuer "YOURFRIEND@YOUR_FRIENDS_EMAIL"
gpg: Good signature from "YOURFRIEND <YOURFRIEND@YOUR_FRIENDS_EMAIL>" [ultimate]

# try it out

If you want to try out sending an encrypted DM but don't know anyone who would be interested in that, you can send an encryped direct message on activitypub (commonly known as mastodon) to me! And then I know that somebody read my post and tried it out, which is pretty cool.

I'm @hack@sy.nthia.dev and my pgp key is https://nthia.dev/pgp.

And If you send me your public key (in whatever manner: link, inline contents, qr code) I can even send you an encrypted reply!