GICT knowledge base
How to Encrypt and Decrypt Files on Linux with age
Published
A file copied to another server or stored in a shared backup folder may be readable by anyone with access to that storage. Encrypting it before the copy means the storage location does not also need your decryption key. The age command does this without a key server or a running service.
This guide uses a public recipient to encrypt a file and a private identity to recover it into a separate directory.
Install age on Ubuntu
Use Ubuntu 24.04 with a sudo-capable account. These commands also work in a Linux terminal on your own computer; a server is not required. If you need a server for storing or processing your files and do not already have one, an interServer VPS is a suitable CPU-based environment. No GPU or publicly accessible application port is needed. Allow disk space for the source, encrypted copy, and recovered copy.
The $ at the beginning of each command is a terminal prompt. Do not copy it. Run the file operations as your normal user, not root.
$ sudo apt-get update
$ sudo apt-get install -y age
$ age --version
The tested Ubuntu package reports 1.1.1. This tutorial uses that distribution package rather than requiring the newest upstream binary. The recipient-file and identity-file options used below are supported by this package; newer features such as post-quantum key generation are outside this procedure.
Create a private identity and a public recipient
Create a fresh working directory. If age-demo already exists, choose another name rather than mixing these files with an earlier run.
$ umask 077
$ mkdir ~/age-demo
$ cd ~/age-demo
$ mkdir keys
$ age-keygen -o keys/identity.txt
$ age-keygen -y keys/identity.txt > recipient.txt
$ stat -c '%a %n' keys/identity.txt recipient.txt
The permission check returned:
600 keys/identity.txt
600 recipient.txt
age-keygen writes the secret into keys/identity.txt and prints only its public recipient. The -y command extracts that recipient into recipient.txt, avoiding manual copying of a long key. The permissions check should show 600 for both files. The umask applies to this shell and makes newly created files private by default; it does not tighten permissions on existing files.
Share the recipient, never the identity. A recipient starts with age1. The identity file contains the secret needed to decrypt. Do not paste its contents into a ticket, Git repository, screenshot, or chat.
Both are on one machine here so you can prove the round trip. For server-side encryption where the server should not be able to decrypt stored copies, generate and retain the identity on a trusted recovery computer, and put only its public recipient.txt on the server. Confirm a recipient through a trusted channel before encrypting important data for someone else; a substituted recipient sends access to the wrong person.
Keep a protected backup of the identity separate from the ciphertext and test that backup before relying on the workflow. Losing every usable copy of the identity means losing access to files encrypted for it. File permissions do not protect a key from root or from a compromised account that owns it.
Encrypt a file without replacing the source
In ~/age-demo, create a new file named report.txt with your text editor. Use this harmless content for the first test:
Quarterly server inventory
Web server: web-01
Database server: db-01
Review date: 2026-09-10
This is synthetic test data, not a password or customer record.
Encrypt it to the public recipient:
$ age -R recipient.txt -o report.txt.age report.txt
$ ls -l report.txt report.txt.age
The command normally completes silently. Check that it succeeded and that report.txt.age exists before copying anything. The .age file is the encrypted copy; report.txt remains readable plaintext. The -R option reads recipients, while -i, used later, reads identities. They serve different purposes.
Only the public recipient is needed for this operation. You can encrypt on a machine that has no private identity at all. Transfer or store the .age file using your existing file-transfer process, not the keys directory. The encrypted file is binary; the extension labels it for people but does not itself provide protection.
For a folder, make an archive first and encrypt that archive as the input file. age does not select directories or implement backup retention, scheduling, or restore history. Keep those concerns in your existing backup workflow rather than treating this one command as a complete backup system.
Decrypt into a new directory and compare
Create a fresh recovery directory. The following command writes to a temporary name and renames it only if decryption returns success:
$ mkdir restore
$ age --decrypt -i keys/identity.txt -o restore/report.txt.partial report.txt.age && mv restore/report.txt.partial restore/report.txt
$ sha256sum report.txt restore/report.txt
The test returned matching hashes:
495f5a7bc4854f9ada950a7ea1595bb5450d65783cf3f5edbaba1cd04a7a2c83 report.txt
495f5a7bc4854f9ada950a7ea1595bb5450d65783cf3f5edbaba1cd04a7a2c83 restore/report.txt
Check the bytes directly as well:
$ cmp report.txt restore/report.txt
$ echo $?
0
The two SHA-256 values should match. cmp is silent when the bytes are identical, and the immediately following echo $? should print 0. Run that status check directly after cmp; another command would replace the status you meant to inspect.
Do not use a recovered file until decryption succeeds. If the first half of the combined command fails, && prevents the rename. In the damage test, age wrote 4,128,768 bytes of a 4 MiB file before rejecting its final chunk. The guarded rename did not happen. A .partial file may therefore still exist; it is not a successful recovery and must not be fed into an importer, archive extractor, or production process.
This comparison proves that the recovered test file matches the original you still possess. The checksum is not a signature, and a checksum delivered by an untrusted sender does not establish who created the file. For a real recovery performed later, you may no longer have the original available; successful authenticated decryption is still essential.
Avoid damaged or overwritten output
- Output paths can overwrite files.
age -ooverwrites an existing output. Use new names and a fresh recovery directory. Never set the output to the source path, and do not repeat a command against your only good recovered copy. - Wrong identity is not missing software. If decryption reports that no identity matched, check that you selected the identity belonging to the original recipient. Generating a new key does not recover an old key’s files.
- Damaged files can leave partial plaintext. An error late in a larger encrypted file can occur after earlier plaintext has already been written. File existence or nonzero size is not a success test. Keep failed outputs separate and obtain an intact copy of the ciphertext.
- A new terminal has its own umask. Run
umask 077again before decrypting sensitive material in a fresh session. An existing destination retains its old permissions even when the command replaces its contents. - Encryption does not remove plaintext. The source, editor backups, and successful recovered files still need normal access controls. Deleting them later is not a guarantee of secure erasure on snapshots, SSDs, or backups.
What file encryption does not protect
Anyone with the public recipient can create a valid encrypted file for you. Encryption protects the contents from readers without the identity, and authentication detects corruption during decryption, but it does not authenticate the sender. Do not run an executable or trust instructions merely because the encrypted container opened successfully.
For one file, this workflow is straightforward. For shared folders requiring individual access revocation, audit trails, or continuous updates, an access-controlled storage service may fit better. Removing a recipient from future commands cannot revoke copies of an older file or plaintext someone has already recovered.
Encryption also does not hide everything about storage: the outer filename, approximate size, and filesystem timestamps remain visible. It does not protect plaintext while a compromised computer is reading it. Keep the recovery identity where you actually trust the machine, and retain a tested key backup.
The result is a separate encrypted copy and a verified recovery path. The 4 MiB control decrypted identically, while the damaged copy failed without being renamed as a completed recovery. Keep the original until you have checked the recovered contents and your key backup; do not confuse a newly created file with a successful decryption.
Related guides
How to Scan Docker Images for Vulnerabilities with Trivy
Scan container images with Trivy without running them, read package fixes, save JSON reports, and distinguish severity-policy failures from scan errors.
Cyber SecurityA Complete Guide to the Zero Trust Security Model
Discover the Zero Trust security model and its importance in modern cybersecurity, including principles, implementation strategies, and common misconceptions.
