Securing Data with Encryption: SSH keys, GPG, openssl

Securing Data with Encryption: SSH keys, GPG, openssl

What You Will Achieve

  • Generate RSA / ED25519 key pairs with ssh-keygen and explain their use
  • Register a public key on a remote host with ssh-copy-id and connect via public key authentication
  • Enter a passphrase only once using ssh-agent / ssh-add
  • Distinguish the uses of SSH port forwarding (-L / -R / -D)
  • Encrypt, decrypt, sign, and verify files with gpg
  • Compute hashes and run basic symmetric encryption with openssl
  • Explain how key file permissions (600 / 700) relate to authentication failures

This is the core of LPIC-1 objective 110.3 "Securing data with encryption". The key to mastering it is separating protection of the channel (SSH) from protection of the data itself (GPG / openssl).

How Does SSH Public Key Authentication Work?

Public key authentication proves "possession of the private key". The client's public key is registered in the server's ~/.ssh/authorized_keys, while the private key never leaves your machine. Because no password is sent over the wire, it is highly secure.

File / Directory Role Recommended permission
~/.ssh/ Holds SSH-related files 700
~/.ssh/id_ed25519 Private key (yours only) 600
~/.ssh/id_ed25519.pub Public key (to distribute) 644
~/.ssh/authorized_keys Allowed keys on the server 600
~/.ssh/known_hosts Recorded public keys of connected servers 644

The flow is a challenge-response: the server encrypts a random value with the client's public key, the client decrypts it with the private key and replies, proving private key possession. The private key never travels over the network.

Steps to Generate Keys and Connect

Step 1: Generate a key pair with ssh-keygen

ssh-keygen -t ed25519 -C "user@example.com"
Generating public/private ed25519 key pair.
Enter file in which to save the key (/home/user/.ssh/id_ed25519):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /home/user/.ssh/id_ed25519
Your public key has been saved in /home/user/.ssh/id_ed25519.pub

-t specifies the key type. Per man ssh-keygen, the values for -t are dsa / ecdsa / ecdsa-sk / ed25519 / ed25519-sk / rsa. ED25519 is recommended today; for RSA, specify a key length such as -b 4096. -C is a comment (an identifying label appended to the public key). The passphrase is an extra key protecting the private key; it can be empty, but setting one is safer.

ssh-keygen -t rsa -b 4096

You typically choose RSA only when you must connect to an older server that cannot interpret ED25519.

Step 2: Register the public key on the remote host

ssh-copy-id user@server.example.com
Number of key(s) added: 1

Now try logging into the machine, with:   "ssh 'user@server.example.com'"
and check to make sure that only the key(s) you wanted were added.

ssh-copy-id appends your public key to the remote ~/.ssh/authorized_keys and adjusts permissions. To do it manually, add the public key content as one line in authorized_keys. Never send the private key (the file without .pub).

Step 3: Connect with public key authentication

ssh user@server.example.com
Enter passphrase for key '/home/user/.ssh/id_ed25519':
Last login: Fri May 30 10:00:00 2026 from 203.0.113.10
user@server:~$

If the public key is registered, you log in with only the private key passphrase, not a password. When something fails, check the detailed log with ssh -v user@host.

Step 4: Cache the key with ssh-agent

eval "$(ssh-agent -s)"
ssh-add ~/.ssh/id_ed25519
ssh-add -l
Agent pid 4521
Enter passphrase for /home/user/.ssh/id_ed25519:
Identity added: /home/user/.ssh/id_ed25519 (user@example.com)
256 SHA256:abc...xyz user@example.com (ED25519)

ssh-agent is an authentication agent that holds private keys in memory. Once you register a key with ssh-add, later connections no longer prompt for the passphrase. ssh-add -l lists registered keys and ssh-add -D removes all of them.

Step 5: Fix the permissions

chmod 700 ~/.ssh
chmod 600 ~/.ssh/id_ed25519
chmod 644 ~/.ssh/id_ed25519.pub

OpenSSH refuses to use a private key that others can read. Setting ~/.ssh to 700 and the private key to 600 is the baseline. Skipping this is the classic cause of "the key exists but authentication fails".

What Is the Difference Between the Three Port Forwarding Modes?

-L is local forwarding (through a local port to a service on the remote side), -R is remote forwarding (a remote port to a service on your machine), and -D is dynamic forwarding (a SOCKS proxy). Choose by direction and purpose.

Option Name Typical use
-L local:host:hostport Local forward Reach an internal DB through a bastion from your machine
-R remote:host:hostport Remote forward Let a remote host reach a service on your machine
-D port Dynamic forward (SOCKS) Route browser traffic through SSH
ssh -L 8080:internal-db:5432 user@gateway
ssh -R 9000:localhost:3000 user@remote
ssh -D 1080 user@gateway

As defined for -L / -R / -D in man ssh, this carries application traffic over SSH's encrypted channel. With a tunnel in place, even a plaintext protocol can be transported safely.

How Do You Encrypt and Sign Data Itself with GPG?

GPG (GnuPG) is an implementation of the OpenPGP standard that encrypts and signs files themselves. While SSH protects the channel, GPG protects data you store or distribute. You encrypt with a public key, and only the matching private key can decrypt.

Generate a key pair

gpg --gen-key
gpg --list-keys
pub   ed25519 2026-05-30 [SC]
      ABCDEF0123456789ABCDEF0123456789ABCDEF01
uid           [ultimate] User Name <user@example.com>
sub   cv25519 2026-05-30 [E]

gpg --gen-key prompts for a name and email interactively and creates a key pair. --list-keys lists public keys and --list-secret-keys lists private keys.

Distribute and import public keys

gpg --export -a user@example.com > mypubkey.asc
gpg --import friend_pubkey.asc

--export -a writes a public key in ASCII (armored) form. The other party imports it with --import. To encrypt for someone, you need their public key on hand.

What you distribute is the public key. Never hand over the private key produced by --export-secret-keys. If the private key leaks, every ciphertext addressed to that key can be decrypted and signatures can be forged.

Encrypt and decrypt a file

gpg -e -r user@example.com secret.txt
gpg -d secret.txt.gpg > secret.txt
gpg: encrypted with cv25519 key, ID 0123456789ABCDEF, created 2026-05-30
      "User Name <user@example.com>"

Encrypting with -e (--encrypt) and -r (recipient) produces secret.txt.gpg. Decrypt with -d (--decrypt). Only someone holding the specified recipient's private key can decrypt.

Sign and verify

gpg --sign document.txt
gpg --verify document.txt.gpg
gpg: Signature made Fri 30 May 2026 10:00:00 JST
gpg:                using EDDSA key ABCDEF0123456789ABCDEF0123456789ABCDEF01
gpg: Good signature from "User Name <user@example.com>"

--sign signs with the private key, guaranteeing the author and detecting tampering. --verify checks it with the signer's public key. Encryption (confidentiality) and signing (authenticity) serve different purposes; do not confuse them.

What Can You Do with openssl?

openssl is a toolkit providing TLS and cryptographic functions. It handles hashing, symmetric encryption, key and certificate generation, and more. For LPIC-1, focus on basic hashing and encryption.

openssl dgst -sha256 file.txt
openssl enc -aes-256-cbc -pbkdf2 -in file.txt -out file.enc
openssl enc -d -aes-256-cbc -pbkdf2 -in file.enc -out file.txt
SHA256(file.txt)= 9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08
enter AES-256-CBC encryption password:

openssl dgst -sha256 computes a hash (a fingerprint of the file). openssl enc is symmetric encryption that uses the same password for encryption and decryption. Add -pbkdf2 for key derivation. The difference from GPG is that enc is password-shared, whereas GPG protects data with public key cryptography.

Common Mistakes and Fixes

Mistake 1: Loose permissions on the private key or ~/.ssh

If ~/.ssh is 777 or the private key is 644 so others can read it, OpenSSH ignores the key for security reasons and either falls back to password authentication or refuses to connect. Fix it with chmod 700 ~/.ssh and chmod 600 ~/.ssh/id_*.

Mistake 2: Ignoring the known_hosts host key change warning

Rebuilding a server changes its public key, producing the warning REMOTE HOST IDENTIFICATION HAS CHANGED! on connect. This is an important warning that may also indicate a man-in-the-middle attack. Once you confirm the change is legitimate, remove the matching line from known_hosts with ssh-keygen -R hostname and reconnect.

Mistake 3: Confusing public and private keys in GPG

Use the recipient's public key to encrypt and your own private key to decrypt. Distribute only the public key. Confusing --export (public key) with --export-secret-keys (private key) and sharing the private key defeats the purpose of encryption.

Mistake 4: Not setting or managing a passphrase

If the private key has no passphrase, anyone who steals the key file can impersonate you. Set a passphrase and use ssh-agent to reduce how often you type it. Manage the GPG private key passphrase the same way.

Mistake 5: Sending the private key instead of the public key to the server

What you register in authorized_keys is the public key ending in .pub. Using ssh-copy-id registers it correctly and automatically. When copying manually, be careful not to send the private key (id_ed25519).

Troubleshooting

Symptom: A password is requested even though the public key is registered

Cause: Excessive permissions on the private key or ~/.ssh, or a faulty entry in authorized_keys

Check:

ssh -v user@host
ls -ld ~/.ssh
ls -l ~/.ssh/authorized_keys

Fix: Set chmod 700 ~/.ssh and chmod 600 ~/.ssh/authorized_keys. In the ssh -v output, find where the key is offered or rejected.

Symptom: Connection stops with a host key change warning

Cause: The server's host key changed and no longer matches the known_hosts record

Check:

ssh-keygen -l -F hostname

Fix: Once you confirm the change is legitimate, delete the old record with ssh-keygen -R hostname and reconnect. If you cannot explain the change, abort the connection and investigate.

Symptom: gpg --decrypt cannot decrypt

Cause: The matching private key is not in your keyring, or you encrypted with the wrong recipient

Check:

gpg --list-secret-keys

Fix: Confirm you have your private key. Without it, that ciphertext cannot be decrypted. When encrypting, specify the correct recipient with -r (yourself, if you will decrypt it).

Completion Checklist

  • [ ] Generated a key pair with ssh-keygen -t ed25519
  • [ ] Registered the public key on a remote host with ssh-copy-id
  • [ ] Connected via public key authentication
  • [ ] Added the private key to ssh-agent with ssh-add
  • [ ] Set ~/.ssh to 700 and the private key to 600
  • [ ] Verified file encryption and decryption with gpg
  • [ ] Computed a hash with openssl dgst

Summary

Purpose Command Protects
Generate key ssh-keygen -t ed25519 SSH connection authentication
Register public key ssh-copy-id user@host The remote authorized_keys
Cache key ssh-add Passphrase entry count
Encrypt data gpg -e -r user file Stored / distributed data
Sign / verify gpg --sign / --verify Authenticity
Hash / symmetric openssl dgst / openssl enc Integrity / password-shared encryption

SSH protects the channel; GPG and openssl protect the data itself. Master this division of roles and the discipline of key file permissions, and 110.3 becomes a reliable source of points.

Next Reading

Continue Your LPIC-1 Journey

LPIC-1 Hub

  • LPIC-1 Learning Hub — Full LPIC-1 article map, progress tracking, and exam objective coverage

Practice