In Linux, a common command-line utility to perform PGP actions is the gpg program. See a small reference here:
Signing and Verifying
Putting a signature under a message can prove that a certain private key owner has written the message. Anyone can verify it with your public key, but only you can create it with your private key. This is often found in the following format:
-----BEGIN PGP SIGNED MESSAGE-----Hash: SHA512Hello, world!-----BEGIN PGP SIGNATURE-----iQGzBAEBCgAdFiEEQctSPuIHmG7eGC/HYLG3XetyYecFAmSRkqsACgkQYLG3XetyYec2fwwAuwOmfZJlttuFxOlLP6RPD1yMD8XDDfRUxg96NvDvzYNnntZhU6Jeevvf0rdogx5NsRZMPFYb9ysXlO/RDk9ZS4w8vNvZtiqDBQjjOKLblsU/sjgC7SQKLPnDTZiQYbqBDH3DQIGgkbmU3fiOrps8Atu0dJR7o0y6Kf9/HqTBN2nCvA0jnhhXTA00R5f6h+KXtBcMw29aHeLSO3c27+8LelTLKSyXEuUNev8ssbt5T7JdorckJzq3cwUGzkXAtEMOzvOYd9SeftXeThTmMoiT1I8ZaBgJ60MnxVaaJUZAahQSx0wHtIV7NZCzauNfR14XvAyUSyPbKLDI98+qygn/ljgI0yU5nRj5fvRptuJBDUWywKJF+Zj7iGRLopPyb6BS5kSOba1PgubgICoKGMyWWWVi33OZjoFqNVq4W4i/tNL3+oQbVBpfqXYofRAx5C9tAv6moRRnyyE2gZolCs7grdZVqpbTMOQzMJMjwjOfG+Rmsfc81zi1v3Z3HzEdXwrj=RtST-----END PGP SIGNATURE-----
It is very recognizable and easy to understand. The first part is the readable plaintext message, and the second part is the signature of that text above, signed (encrypted) with the sender's private key. If anyone wants to verify the validity, they would need to take your public key, and decrypt the signature to be left with an exact match of the text above.
If you don't have a keypair yet, you can generate one with:
$ gpg --gen-key
or import an existing one with:
$ gpg --import [keyfile]
To then verify it, make sure to first have the public key from the sender imported:
$ gpg --import sender.pub
Afterward, you can verify any messages they send came from that key:
$ gpg --verify msg.txt.asc
gpg: Signature made Tue Jun 20 13:51:07 2023 CEST
gpg: using RSA key 41CB523EE207986EDE182FC760B1B75DEB7261E7
gpg: Good signature from "Jorian" [ultimate]
Encrypting and Decrypting
If a message is intended for only a specific person to be able to read it, you can encrypt it with their public key so only they can decrypt it with their private key. An encrypted PGP message looks like this:
It is generated by encrypting the message with the recipient's public key, which means you first need to have imported their key like shown before. Then use the following options:
-e: to select encryption
-r [name or ID]: to select the recipient public key
-a: Add "armor" to the resulting file, meaning it is simply an ASCII format in Base64 and BEGIN/END instead of the regular .gpg binary format
For example:
$ gpg -a -e -r Jorian message.txt # Using saved name
$ gpg -a -e -r 41CB523EE207986EDE182FC760B1B75DEB7261E7 message.txt # Using ID
$ cat message.txt.ascl
-----BEGIN PGP MESSAGE-----
hQGMA+DFCnh6q6yZAQv/RNVXrpb4awnHSOQUkr0dn32NvgmwwXXXCKChAr17SpAt
Tu7ppTjSBIfSYDSGvLNHYDQdKBaqHxR+YGfiUKKgJahqTX8n17HgG4FLESWyWJJq
adQpE3sr9d+PpexZ/L1i+dtTk5XYkxXtbXXg4MvgLj/YWKNhPoTEEzlSxYIW1sjB
/7yyZuLcG0Y6DEt6/apnpF2HWh+ygFM/Xhx4RplM0HwpE3fdYZQxNVYcoMgEsm51
PQfaHml5lDAviJNdv7tMpS90wE6jWJMPj1GojOx0oQK4nM+k62Bppj/OVSo5RMkl
N6i1SYngyKcTVN8EF7g60lp3Z6tKd/a781ecsdXAJyNXP0/ccfgkzaMEHuOkfY66
9cig0RbglG11uXBygeU+V5mriKV2lw+I8rW5uIE9ZZgfW8e5fuOkBDfZ44uEYKrO
ZPBCWFXSwKrbKSUw+KOJiiJjk+7An3/0a/rrM2RcQzx9yfIWHeVl5Psi697LO3ps
PsQmjsIDJg/77UzFWUT50lQBydrV62gwxaC2j2i6X2ctffGMUReovang9IDfmQP+
2kDnsSiT9HQtLRMex0I9S+ZIK4CehgjdCWqCW+74HO1Tz/RRhdjoONSBkU8506kK
3d/nhX0=
=LSK8
-----END PGP MESSAGE-----
When the recipient wants to read this message, they have to decrypt it with their private key. Simply using the -d option will automatically find the correct key used and owned by you:
$ gpg -d msg.txt.asc
gpg: encrypted with 3072-bit RSA key, ID E0C50A787AABAC99, created 2023-06-18
"Jorian"
Hello, world!
You can also encrypt and sign at the same time, using both options ( -s and -e) together
Python
Using the PGPy module you can easily automate any PGP tasks like generating keys, signing/verifying messages and encrypting/decrypting messages.
This can also be useful to generate low-level keys where you can easily control exactly what data is in the name, comment or email. If an application parses these fields in some what it may be worth trying to inject unexpected data in here like any other field on a website.
Here is a simple example of generating a key and signing a message: