Ciphertext can be altered. Sign and Verify messages or get fucked

A reminder to use the Sign and Verify features of PGP to prevent attacks that most users are probably unaware of.

Ciphertext can be altered. Sign and Verify messages or get fucked

#OpSec, bitches!

Encrypted messages can be altered! Other attacks aside, arbitrary text can be injected into an encrypted message. Worst case? Oh, idk. Maybe a request to change session keys and then crunch! bang! Man-in-the-middle. Man in prison. Man in casket?

The fix: Sign and verify.

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA256

Signing messages creates a hash of the text.
For unencrypted messages, this proves the identity of the sender.
For unencrypted and encrypted messages, it assures message integrity.
-----BEGIN PGP SIGNATURE-----

iHUEARYIAB0WIQQbz8G7d4axAhs99w8A9WRzKL4s8QUCYDdj+QAKCRAA9WRzKL4s
8ZN2AQCSqm856D73cfDbRnfe5XtR9/SPSqpb4QDNqa0zaEnnUQEAoOvm/UMeoeEc
qF0pjhaBrvrF1juXE3os4aNxUIbmMgo=
=EmZi
-----END PGP SIGNATURE-----

Above is a cleartext signature for you to practice on. Import my key, bitch!

Pgp signatures can be thought of as checksums like those on file downloads, torrent pieces, etc- cryptographically secure checksums which only the holder of the secret key and its password can produce by hashing the message with the private signing key. When verified, signatures can alert us to tampering that might otherwise go undetected. Encrypting a message is not an assurance of its integrity. Signing it is.

A "good signature" means the text later compared to the hash value is correct. It proves that the keyholder sent this exact body of text or ciphertext and that it hasn't been altered since it was signed.

I recommend always doing this step for yourself because some email products in the past have failed to manage signature verification properly and produced misleading results with potentially disastrous consequences.

How to sign:

At its simplest:

gpg --sign

Press enter and gpg will wait for input. Paste your data. Press CTRL+D when done. Tada! Now some details and examples.

First, I get the fingerprint from the key I want to use for signing.

I echo some testdata into a file and then sign it with gpg --sign [filename]. This reads the data, signs it, and writes the signature out to [filename].asc.  I used some extra options here.

--local-user=<"Name On Key" OR fingerprint>

will override the system default and force use of the specified key instead.

--armor

This option creates "ascii-armored" output which is better for pasting on forums or in emails.

You can also add the --symmetric --encrypt options to your --sign command to password-lock the signed message like this:

gpg --armor --encrypt --symmetric --local-user=[your signing key name or fingerprint] --sign [filename]

(prompts for password)

To sign and encrypt using someone's public key:

gpg --armor --encrypt --recipient=[recipient name or fingerprint] --sign [filename]

Important: When encrypting to a public key, gpg may throw an unhelpful error if the recipient tries gpg --verify [filename]. Using gpg --decrypt will decrypt the message AND verify the signature.

You can also encrypt manually before signing, which will allow verification before decryption:

gpg --armor --encrypt --recipient=[name or fingerprint] [input-filename]

gpg --armor --sign [filename]

Now we have a new signature file testfile.asc. One package ready to send. Let's have a peek at the contents. This would be readable if --clearsign were used instead of --sign.

If you want to avoid writing files to disk, use gpg --sign without a filename. Gpg will await input. Write or paste your message, then press CTRL+D when done.

The option --detach-sign creates a detached signature containing ONLY the signature and none of the message data, encrypted or otherwise. No example. You can figure it out.

How to verify a signature:

At its simplest:

gpg --verify will await your input. CTRL+D when done. Some details and examples:

You must have the signer's public key. If it's in your keyring/keybox, then it'll be found automatically. If the file has an embedded signature:

gpg --verify [filename]

Also shown is gpg --decrypt [filename] which extracts the signed embedded data and automatically verifies the signature.

If you want to paste a signed message block, don't specify a file:

gpg --verify
Press enter, paste the message, end with CTRL+D.

gpg --decrypt can be used like this, too.

Again, it also verifies the signature.

To verify a file with a detached signature like a Linux distro image with a separate signature file:

gpg --verify [signature file] [file being verified]

No example for this one either.

Warning:

Check WARNINGS in your distro's gpg man gpg page for gotchas, and the section regarding --verify. Here's one example:

If  you are going to verify detached signatures, make sure that the program knows about it; either give both filenames on the command line or use  ‘-’  to  specify STDIN.

Further reading for crypto nerds and source for "encrypted messages can be altered": Efail: Breaking S/MIME and OpenPGP Email Encryption using Exfiltration Channels