What you describe sounds like OpenPGP, using the terminal program gpg. Recent Tails includes GnuPG and its graphical interface, Kleopatra; you don’t need to install anything or use sudo. Tails documentation
The commands below cover the workflow you listed. Replace the example names and fingerprints with the ones from your exercise.
The key relationships are:
| Task | Key used |
|---|---|
| Somebody encrypts a message for you | Your public key |
| You decrypt that message | Your private key |
| You encrypt a message for somebody else | Their public key |
| You sign a message | Your private key |
| Somebody verifies your signature | Your public key |
Your public key can be shared. Keep your private key and its passphrase private.
1Open Terminal and prepare a working folder
Run these commands individually:
gpg --version
umask 077
mkdir -p ~/pgp-exercise
cd ~/pgp-exercise
umask 077 makes newly created files accessible only to your user.
Tails-specific point: saving a file in your home folder does not normally preserve it after shutdown. If your VM supports configured Persistent Storage, the GnuPG feature preserves your keyring; the Persistent Folder feature preserves files saved there. An ordinary ISO-based VM might have neither, so complete the exercise before shutting down. Persistent Storage, Tails in a VM
2Create your public/private key pair
gpg --full-generate-key
Follow the prompts:
- Use the algorithm and size specified by the exercise. If none is specified, RSA and RSA, 3072 bits, is a broadly compatible choice.
- Choose an expiration, such as
1y, unless instructed otherwise. - Enter the name and email required by the exercise. The comment can be blank.
- Confirm and set a strong passphrase when prompted.
GPG creates both keys and stores them in its local keyring automatically. You don’t create the public and private keys separately. GnuPG key-generation reference
Display your private keys and their fingerprints:
gpg --list-secret-keys --keyid-format long --with-fingerprint
Find your new key. The long hexadecimal line beneath sec is its primary fingerprint, which identifies it precisely.
Copy that fingerprint, without spaces, into this command:
my_key='PASTE_YOUR_FULL_FINGERPRINT_HERE'
This defines a terminal variable for the following commands. Replace the placeholder first.
3Export both keys as readable text files
gpg --armor --output my-public-key.asc --export "$my_key"
gpg --armor --output my-private-key.asc --export-secret-keys "$my_key"
The second command may ask for your passphrase.
--armor produces ASCII-armored text: a text representation of the key, suitable for copying into a website. It does not reveal the mathematics in a human-readable explanation.
Check your public key:
cat my-public-key.asc
It should look like:
-----BEGIN PGP PUBLIC KEY BLOCK-----
...
-----END PGP PUBLIC KEY BLOCK-----
Your private export begins with -----BEGIN PGP PRIVATE KEY BLOCK-----. Do not submit that file to the website or send it to another person.
Without --armor, GPG exports binary files:
gpg --output my-public-key.gpg --export "$my_key"
gpg --output my-private-key.gpg --export-secret-keys "$my_key"
You only need those binary exports if the exercise requests them. Changing a filename from .gpg to .asc does not convert its contents. GnuPG export reference, ASCII armor reference
4Save and import somebody else’s public key
If the website gives you a text block, run:
cat > recipient-public-key.asc
Then:
- Paste the entire public key block, including its
BEGINandENDlines. - Press Enter after the final line.
- Press Ctrl+D to finish saving.
Here, cat is receiving text directly; your pasted text is not being executed as terminal commands. In Terminal, paste is usually Ctrl+Shift+V.
Inspect the key before importing:
gpg --show-keys --with-fingerprint recipient-public-key.asc
Compare its full fingerprint with the fingerprint supplied by the exercise or another trusted source. A name or email alone doesn’t authenticate a key.
Import it into your keyring:
gpg --import recipient-public-key.asc
List your public keys:
gpg --list-keys --with-fingerprint
Set another variable using the recipient’s primary fingerprint:
recipient_key='PASTE_RECIPIENT_FULL_FINGERPRINT_HERE'
Importing adds the key to your keyring; it doesn’t prove who owns it. GnuPG key-exchange guide
5Encrypt a secret code or a message
A code and a longer message use the same encryption operation. First save the plaintext:
cat > secret-code.txt
Type or paste the code, press Enter, then Ctrl+D. This avoids putting the secret itself in a shell command saved in command history.
Encrypt it to the recipient:
gpg --armor --output secret-code.asc --encrypt --recipient "$recipient_key" secret-code.txt
Display the result:
cat secret-code.asc
Copy the entire block into the website:
-----BEGIN PGP MESSAGE-----
...
-----END PGP MESSAGE-----
For a longer message:
cat > message.txt
Enter the message, then Enter and Ctrl+D.
gpg --armor --output message.asc --encrypt --recipient "$recipient_key" message.txt
cat message.asc
If GPG warns that the key’s ownership is unverified, confirm only after checking its fingerprint. You don’t need to mark someone else’s key “ultimately trusted” to encrypt to it.
Only the recipient can normally decrypt these outputs. To make a message decryptable by both the recipient and yourself, include both keys:
gpg --armor --output message-for-both.asc --encrypt \
--recipient "$recipient_key" --recipient "$my_key" message.txt
Encrypt locally and paste only the ciphertext into the website when the task calls for confidential communication. Tails specifically advises against composing confidential plaintext in a browser. GnuPG encryption reference, Tails guidance
6Decrypt a message somebody sends you
They must have encrypted it to your public key.
Save their encrypted block:
cat > received-message.asc
Paste everything from -----BEGIN PGP MESSAGE----- through -----END PGP MESSAGE-----, then Enter and Ctrl+D.
Decrypt directly to the terminal:
gpg --decrypt received-message.asc
Or save the plaintext:
gpg --output decrypted-message.txt --decrypt received-message.asc
cat decrypted-message.txt
Enter your private-key passphrase if prompted. GPG automatically selects the appropriate private key.
You don’t need the sender’s public key to decrypt. You need it to verify their signature if they signed the message. Importing their public key cannot fix a No secret key error: that error means your keyring lacks a usable private key for the message’s recipient. GnuPG decryption reference
7If “encrypt with a password” is requested instead
This is a different mode: it uses a shared passphrase instead of the recipient’s public key.
gpg --armor --output password-encrypted.asc --symmetric message.txt
GPG asks you to choose the encryption passphrase. Decrypt with:
gpg --decrypt password-encrypted.asc
The recipient needs that same passphrase. This passphrase is separate from the passphrase protecting your private key. GnuPG symmetric encryption
8If signing is also part of the test
Sign and encrypt a message:
gpg --armor --output signed-encrypted.asc \
--local-user "$my_key" --sign --encrypt \
--recipient "$recipient_key" message.txt
For a signature stored separately from the original file:
gpg --armor --output message.sig.asc \
--local-user "$my_key" --detach-sign message.txt
Verify that detached signature with:
gpg --verify message.sig.asc message.txt
The verifier must have the signer’s public key. “Good signature” confirms that the signature matches the message and key; the checked fingerprint establishes whose key it is. GnuPG signature reference
The three distinctions to remember during the test are: export shares a key; import adds a key; encryption uses the recipient’s public key, while decryption uses your own private key.