This is a very basic guide to use GPG (GNU Privacy Guard), the free software version of the classic PGP (Pretty Good Privacy) tool for signing, encrypting and verifying information. It can be handy if your Email client does not directly support it. This guide explicitly does not cover creating and maintaining keys and keyrings.
For this tutorial we have the following two individuals: Angel, with email address angel@triptico.com
and Johannes, with email address johannes@comam.es
. They both have GPG installed on their systems and have valid keys. Additionally, each user have another one's public key installed in ther keyrings.
Also, there is a two line message they want to share:
I am the voice of Mother Earth, from whence all horrors have their birth.
Signing
Angel wants to send the creepy message to Johannes. Also, he wants to be sure that Johannes can check that he is who really sent the message. So he runs the following command in its terminal:
gpg -s --clearsign
GPG politely says the following:
You need a passphrase to unlock the secret key for user: "Angel angel@triptico.com" 1024-bit DSA key, ID 70C9B100, created 2012-11-07 Enter passphrase:
This operation implies the use of Angel's private key, that is password-protected inside his keyring. If the password is correctly entered, GPG waits silently for text from its standard input. Angel pastes the message and GPG dumps the following:
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 I am the voice of Mother Earth, from whence all horrors have their birth. -----BEGIN PGP SIGNATURE----- Version: GnuPG v1 iEYEARECAAYFAlvrxGIACgkQ5CXHVHDJsQBOagCfQAFQoZyFfegGZUa8oWwn/srg 1RwAoMFcDABbLpqaqpwIVqv5U4pYvdVb =q64b -----END PGP SIGNATURE-----
This piece of text (including the BEGIN... and END... lines) can be pasted to the email body of a message sent to Johannes. Please note that you can write whatever you want outside the PGP boundaries and the message will still be considered valid when the signature is checked. So this can be the full email body:
Hey, Johannes. This is what was said: -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 I am the voice of Mother Earth, from whence all horrors have their birth. -----BEGIN PGP SIGNATURE----- Version: GnuPG v1 iEYEARECAAYFAlvrxGIACgkQ5CXHVHDJsQBOagCfQAFQoZyFfegGZUa8oWwn/srg 1RwAoMFcDABbLpqaqpwIVqv5U4pYvdVb =q64b -----END PGP SIGNATURE----- Best regards, Angel
Of course, the surrounding text must not be considered signed text. This is a common mistake.
Checking signatures
Johannes receives the message in his Inbox. He's absolutely unsure if it's really Angel who quoted the eerie text; so, he just calls GPG with no arguments:
gpg
And gets the following reply:
gpg: Go ahead and type your message ...
Johannes selects and copies the full message body and pastes it into GPG's standard input. Then the program replies:
I am the voice of Mother Earth, from whence all horrors have their birth. gpg: Signature made Tue Nov 13 15:02:38 2018 CET using DSA key ID 70C9B100 gpg: Good signature from "Angel angel@triptico.com"
So Johannes can be confident than Angel really sent the two-line message (the rest of the text is considered irrelevant and is ignored). GPG does not need any password to check the signature: all it needs is Angel's public key that it's stored in Johannes' keyring but not protected in any way (Angel's public key can be shown in his web home page or printed and glued on the street lamps of the town if he wants, as it's not sensible information).
Please note that, though GPG apparently mixed the message and its own information, the first one is sent to the standard output stream and the second one to its standard error/status stream; Johannes only sees them together because of the way his terminal shows these channels by default.
Tampering detection
Let's suppose some evil being tries to feed its dirty lies to Johannes, trying to take advantage of the confidence between both and impersonating as Angel. So it somehow obtains a copy of the message and does some subtle changes:
Hey, Johannes. This is what was said: -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 I am the voice of Mother Moon, from whence all horrors have their doom. -----BEGIN PGP SIGNATURE----- Version: GnuPG v1 iEYEARECAAYFAlvrxGIACgkQ5CXHVHDJsQBOagCfQAFQoZyFfegGZUa8oWwn/srg 1RwAoMFcDABbLpqaqpwIVqv5U4pYvdVb =q64b -----END PGP SIGNATURE----- Best regards, Angel
Johannes repeats the previous operation but gets the following output
instead:
I am the voice of Mother Moon, from whence all horrors have their doom. gpg: Signature made Tue Nov 13 15:02:38 2018 CET using DSA key ID 70C9B100 gpg: BAD signature from "Angel angel@triptico.com"
That BAD signature...
thing should trigger all kind of alarms.
The GPG tool also returns different output values for valid and invalid operations that can be useful in scripts and programs. If you are not a programmer nor a sysadmin, you can ignore this.
Encrypting
But Angel may occasionally consider that proving his authorship is not enough; he wants the message to be absolutely hidden to anyone but Johannes. So he opts for PGP/GPG encryption, invoking the command
gpg -e -a -r johannes@comam.es
and pasting the two-lines message into GPG's standard input. GPG barfs the following wall of text:
-----BEGIN PGP MESSAGE----- Version: GnuPG v1 hQQOA6n6KzujHJfZEBAAkrlIZp/8IpWhw/H4pjCCzl1GgDvpLiqAvw4b1x9SXcPO bH+yp9M8K34+Slp7QIsBWWp+Z49ZAWeendMSW32iMoxakqt4K2PV27S8qgKAqqPk bWjCFmJ7ERIy1XSxarSUJaRzvWhwXI/9NVecei6boogSlowxce1GMvranzMJKR3J RrMR5AsfHWpnjyvcOjNV+o/OGrE6avPitW4ieWX0PzrLdgXS6tkwFUu9pOeB6OF+ YRgVQKwtcEoPk92PHBGlvfahvT3KbWaso6OOa7mQHI+YgjbA3g2pCDobcsm30wED 2Sw2XbU17KQWKU5YUm/RMNhsvYFrYnBA/jiHzqmsw4YeJrImu2MfkjScTgiAdL3S hIqGz3+AEBH+lTLHKPF3spQV9GDkn2es6DpRmxVF5TOEsb1toUznAqsADwz0Edlb 3FEzeN7Kizui8UJ+HR6al+UiDm0X5v03r1tCMjxmZnq4fkmDG5/tH+j1319s33G7 xDf/upUw1W5XLd+zBgdiTHD1ADxT4fWFiRH6by+CLTdFwt62mREmd1lW6YxwhMEV RGGZQzyLp3uVOg1z4jT2q7bz4MOBEPxY1L44zOENkH54yIITQ46Ambiwc572iJQQ /vP23oFRDJQdvHndxjlbFA2hJMSRavzTn3VzUYJzPGbnB2JzULUyqOH/obL4TMYP /2oxdkJjqQu8Z4xtZOPne5r7q4Ml8mIPtb+h2TbC0hHLi1DDqOQyLJcMmeSKMr3T XAOphMzbaHJYBODJB5w86Qxw6wAah1/+j6525NeHYYLPGACb9n8ujnXQP3l/Kpf6 9/a2+0g3uRCi8GoriLHQN2slEg0hAgSI8t217HTC0fWeNtkVqInd7qUcE04RNa/e 0nhVXDdbhTRMBkLfSRc/3wELVxrevo0K+bEwPUrJgX/9UROiP0lWJoSE0ezWhdCF 4XK/K6RQr+WZE6GjpfzTuqDZNjQdphcV2xnTKM5DnauQNOX3+p2T+Ri/8JmnF+xx z3MGIxtNWIq1u71ykZZbaNVMRniGQ3QRwJiP7/DN2N08Sz4QO3cjqseK6TeCz+Av 3vWGP339NUVKS/QHORwmoOQHm9AKwgqQedtgHn/u2hQpLLE35pCZOv5/GgAeJl4d /w8Qd7xNKDSVZEN82cYb5LJsY/Z0vVaqII66bm+iZQgdaa+uuNGtVITU3lgRMAJP Z0SBbzmNYE/4iLe/B79JK+057KjGlnpswtaYOwe0jS4RB9XRcgE7KBryo4o6h9E9 udt0WF2h05iHzK7i1ewMJif7WszadnFXG8DifsFiteeEARmetLi89WiSVYdSiFsI xRhqIzGA0nz3XWuEBNw00UAl0vtkvDlhGEtSAW19MScc0oAB0TFPswUkicX36SN3 8kZHiLCmIbucq33h+3TgEtiFjXj+pWFjlz4mTTRAvnr+nYn7FDTgblFMF/NJOXZq lSZNeF6PkngjK1+hZTogMBN5OL1iFP1D+IP+7ANydQdQL56V6yaU4YOtJv++l2F4 ghA5wgMRlC9MNWRzptK2qZJmdQ== =NXsq -----END PGP MESSAGE-----
Given that GPG has everything it needs to encrypt a message to Johannes (i.e. his public key), no password nor any more information is requested.
Note that, when the message is encrypted, Angel has no way of decrypting it because he does not have Johannes' private key. There is no other way of decrypting this message than using that key.
As with signing, any text can be written surrounding the PGP boundaries. Also, it should not be trusted, as it's not really part of the message.
Decrypting
Johannes receives the block of garbage and proceeds the same as with the signed message:
gpg
But like every time a private key is involved, GPG asks for the password to the Johannes' keyring:
You need a passphrase to unlock the secret key for user: "Johannes johannes@comam.es" 4096-bit ELG-E key, ID A31C97D9, created 2012-11-07 (main key ID 70C9B100) Enter passphrase:
If it's entered correctly, GPG waits for text from its standard input. Johannes copies the full message into it and GPG dumps the omen from Mother Earth with some additional information:
gpg: encrypted with 4096-bit ELG-E key, ID A31C97D9, created 2012-11-07 "Johannes johannes@comam.es" I am the voice of Mother Earth, from whence all horrors have their birth.
If the encrypted message is garbled someway, GPG will complain about the data block integrity:
gpg: CRC error; C73B95 - 357B2A
Encrypting and signing
For complete paranoia, a message can be encrypted AND signed. This is how it's done from Angel's view:
gpg -es -a -r johannes@comam.es
As it needs Angel's private key for signing, the passphrase for his keyring is requested. After pasting the two-line message into GPG's standard input, The response is another scary block of garbage:
-----BEGIN PGP MESSAGE----- Version: GnuPG v1 hQQOA6n6KzujHJfZEA/8CkbHeZ5Q3VBpsGia90kKJgWcI3/Wbphi5JoSEpm8ezSl ffUhxoiO4NKM5hcJM+v+dqq7Wo0C4P2YxVnsUPIf9xk/aF6KmZttFU8H3o5/8+48 KYQtp2ZBHlSzuDTIwsQyvXAIgg9CyXUTmdALPGaO6X8Yj+UphHghVu6vF1LwQw0k G9EfnjRmyEWzb+C4Rzvh6Sf0g+OMvuFtFf9fuSMfzAnwv8+U8diyJYusiuPUrNz7 Q0b7be5MBhVlTyTfqpnD3zOsqt5EP1NewZgFn9HSxjmHMOGeaR3ahKEQVDyRglqK 49SsPz402meJf3WrU3HUVsjen5I1q8CrJ+La+uxjodF4JAKhIX1qYJ6hySJI1P+w SjGP66VYNFwsYOSkMMlGsehCPNcaNhxZs3UATjd2RsnSNbcs50l+jEQj35EOXApx fUaCjUisXfTNz4PPl5slkfkQRTJ1nC8IVboOBk1REFmgJ3KhER+MXhsqqH4gMOH8 VuGPh4p8nxX5I1WfFGOCtuXCRLCh2kMLdbVG5oDYEr2vPyfaL5EDDIIgao8v+k8E mLsWrLOGnSrg14IJ6NZR5zWx9ZC9s9ICPBfIgzKCgqb0wpjLiEP453Ymfl4/MRVr L5eXdttOfHHcJIultQcmF4FBlC2pHLXUKyJqkPhnHDnqWCtIwOuZHTS9LY6U5TQP /2Moh6TXe+aJTt0k6k4q9/xhCSIWpeOGq24gLQVS5DPTm+tYLSLm6x8nccPmwB2P FRXa7BQnDZ4PnOOS1lpo3kapZsmwY5upeZJ6ArI1c8hzHEVrducRPHQC2BrQ9/yj cKL7vpQNlHAtaSwI1oYhd+HqQLYUfzpDVxYY3ndk1OEWoNfwLFFcCj4jAMJTwD2J JJFhA7nY4CPggkTAr+8xIhzFbkWRexI+g/hfSH0oMKOidMmqCEsfZZStqwM0pfUW Ufc28AN+9r6n/6c7qOyZ+HWpbETceLfrUuYwLZ8ExzirJvqILWpMEZduYywDrLko 8wH73JGHue+bdhW62MNoF45hOaSTBwB7ZZ9LmjqaADPeBVipZUUJPUpTuRg5k+o5 JfDD6KbbIVl8cqKnLsBRfW5kDov7qKjxZjrbZ88KIa9qk0jrgXc1d0E74Cv/Lvdv L7q1Odd1Wsviug0Rdt5YzENXHqZrlCx0BkxBQWdoWhTurdloNITkWir2rxt50tCs AJlisig+zGQXkfzoiMMagS4MK2K8slyatT7KpbW9Tr0ueMrHN0Rm1kklw+b7/vnp 3x8HHJq2Ia8WU3BoaO5cbD8l2d6st/Nhxgf2e+TxBGN87LSpZPzlSOoUISc1pSPB RdmACYkrPH+6OaaWjY9uzeSygWbVz3p+lBTL6ZICtQvz0sASAU9lY41R3ZsoTWUv /E/fTb4U3y4fTsR4G06Y4gyexh4Yyejh/s2mBc3VG4TCkZyubQilXy8mrhM3NJpj DEG6zZQEMtndp1Wq5z+qcvrJ2AF+j5R4nm7zNdt4XjrXOA+3zfzeD+avnfCjKAhT Jw0kzUrCzj34xc3iScQmwrdLEETk+66Ypv30ZEcdlzTrQUgcXW1WAqfJfaL8CJf1 69oTyoWRAAXkpyJGZoIafzS+Cvjupneybqab1+sL8qajpptQBglCaatioFJrZWnk qt4LUBgD =G+4J -----END PGP MESSAGE-----
The difference is that, when Johannes tries to check the message as he usually do:
gpg
The following is shown:
You need a passphrase to unlock the secret key for user: "Johannes johannes@comam.es" 4096-bit ELG-E key, ID A31C97D9, created 2012-11-07 (main key ID 70C9B100) Enter passphrase:
This should be expected, as it's a message for Johannes' eyes only. The output is a bit different, though:
gpg: encrypted with 4096-bit ELG-E key, ID A31C97D9, created 2012-11-07 "Johannes johannes@comam.es" I am the voice of Mother Earth, from whence all horrors have their birth. gpg: Signature made Tue Nov 13 16:03:20 2018 CET using DSA key ID 70C9B100 gpg: Good signature from "Angel <angel@triptico.com>"
GPG dumps information about the key the message was encrypted for, the message itself and the results of the validation test.
Signing binary files
Sometimes Angel may want to sign a binary file (a zip package, an image, etc.), for the purpose of helping people know that the file he has and the one they have has the same content. But adding PGP/GPG crap to this kind of files cannot be done because it corrupts them; so, you have to use a detached signature. Suppose you have the file
abraham_lincoln_nude.jpg
Then you can sign it by executing
gpg -ab abraham_lincoln_nude.jpg
A familiar prompt from GPG will be shown:
You need a passphrase to unlock the secret key for user: "Angel angel@triptico.com" 1024-bit DSA key, ID 70C9B100, created 2012-11-07 Enter passphrase:
After a successful password GPG creates a file with the same name as the signed one, but with the .asc
extension appended, and that looks like:
-----BEGIN PGP SIGNATURE----- Version: GnuPG v1 iEYEABECAAYFAlvr2GAACgkQ5CXHVHDJsQCeagCfTn72ZUBeVlWwTMvTMcGIbZsL 9q4An0ZDXwAaMb5cyHUsybXoXZ/yjw8U =R3uI -----END PGP SIGNATURE-----
Both the file and the signature can now be made available to others.
Validating signed binary files
Johannes can validate that the binary file and Angel's signature on it match by calling
gpg abraham_lincoln_nude.jpg.asc
Note that both the file and the signature must be on the same folder. GPG shall return the following:
gpg: assuming signed data in `abraham_lincoln_nude.jpg' gpg: Signature made Wed Nov 14 09:10:08 2018 CET using DSA key ID 70C9B100 gpg: Good signature from "Angel angel@triptico.com"
Summary
For signing text (will ask for sender's passphrase):
gpg -s --clearsign < msg.txt > msg.signed.txt
For checking a signed text (no passphrase needed):
gpg < msg.signed.txt
For encrypting text (no passphrase needed):
gpg -e -a -r user@destination < msg.txt > msg.encrypted.txt
For decrypting an encrypted text (will ask for receiver's passphrase):
gpg < msg.encrypted.txt
For encrypting and signing text (will ask for sender's passphrase):
gpg -e -a -r user@destination < msg.txt > msg.both.txt
For decrypting and checking text (will ask for receiver's passphrase):
gpg < msg.both.txt
For signing binary files (will ask for sender's passphrase):
gpg -ab binary_file
For checking signed binary files (no passphrase needed):
gpg binary_file.asc
End notes
Harry can sleep peacefully because he always encrypts and signs his email messages.
Though the examples here are given using GPG version 1, you should really use version 2 (the executable is called gpg2
in those systems that deploy both versions). I've used the older version because one of the features of version 2 is that it includes an agent that asks for passwords in GUI dialogs (if a GUI is available) and retains them for reasonable periods of time. This is of course convenient, but it may make less clear the cases where a passphrase to the keyring is needed.