Привет, Хабр!

Сегодня мы рассмотрим age — современный инструмент файлового шифрования, который за последние пару лет стал твёрдым фаворитом всех, кому надо быстро и надёжно прятать данные.

Что такое age и чем он отличается от GPG

age — это минималистичный CLI и файл‑формат с фиксированным набором примитивов (X25 519 + ChaCha20-Poly1305 + HKDF). Никакой конфигурации, никаких зависимостей. Отсюда вытекают две главные фичи:

  • Простая модель атаки. Вся логика уместилась в пару сотен строк Go‑кода, а значит меньше места для ошибок.

  • Композиция по‑Unix‑ски. age читает stdin, пишет stdout, поэтому его легко встраивать в пайплайны.

В отличие от GPG, age не умеет подписывать, у него нет громоздкого PKI и «зоопарка» шифров. Зато освоить age можно за вечер — а значит меньше «знание‑базы» для вашей команды.

Установка и генерация ключей

В дистрибутивах age давно лежит в репах:

# Debian/Ubuntu
sudo apt install age

# Arch
sudo pacman -S age

Создаём X25 519-пару:

age-keygen -o key.txt

Формат ключей отсылок не требует: public начинается с age1…, private — AGE-SECRET-KEY-1….

Минимальный сценарий: passphrase

# шифруем
age --passphrase -o secrets.txt.age secrets.txt
# расшифровываем
age --decrypt --output secrets.txt secrets.txt.age

В интерактивном режиме CLI спросит пароль с защитой от «echo». Файлы с паролями читаем через --passphrase-file, если автоматизируем.

Шифрование на публичные ключи

Самая безопасная практика — шифровать на X25 519-рецепиенты или на SSH‑pubkey, который уже лежит у коллег.

RECIPIENT=$(grep ^age1 key.txt)     # вытаскиваем из файла
age --recipient "$RECIPIENT" -o report.csv.age report.csv

Несколько адресатов? Просто повторяем --recipient.

Расшифровка через identity

age --decrypt --identity key.txt -o report.csv report.csv.age

age спокойно ест приватные ключи OpenSSH, так что можно не дублировать инфраструктуру.

Потоковое шифрование

Одна из фич — шифрование на ходу. Например, архивируем и сразу шифруем каталог:

tar -cz project/ | age -r "$RECIPIENT" -o project.tar.gz.age

Обратная операция симметрична:

age --decrypt -i key.txt -o - project.tar.gz.age | tar -xz -f -

Никаких временных файлов, всё идёт через конвейер. Это нужно, если у вас CI‑нод мало места или соседний админ любит смотреть в /tmp.

Внутренности формата

Файл age состоит из:

  1. Header. Список станцованных для каждого получателя «энвелопов» с ключом сессии, зашифрованных X25 519 + HKDF.

  2. Payload. Поток ChaCha20-Poly1305 в режиме AEAD, разбитый на 64-килобайтные «чонки» и снабжённый тегами аутентичности.

На чтение age сначала раскладывает header, вытаскивает симметрический ключ и стримит дешифровку блоками. В результате даже гигабайтный файл не кладёт оперативку.

Пример резервного скрипта

#!/usr/bin/env bash
set -euo pipefail

KEY_FILE=$HOME/.keys/backup.txt
TARGET=/var/backups/$(date +%F).tar.gz.age
SRC=/srv/data

tar -c --one-file-system "$SRC" \
  | gzip \
  | age -r "$(grep ^age1 "$KEY_FILE")" -o "$TARGET"

echo "Backup готов: $TARGET"

Пара минут на проверку, cron раз в сутки, и у вас надёжные архивы без мучений с GPG‑агентом.

Написание утилит на Go

age имеет библиотеку filippo.io/age. Пример мини‑катализатора, который шифрует stdin в stdout:

package main

import (
	"io"
	"log"
	"os"

	"filippo.io/age"
)

func main() {
	const recipientStr = "age1gde3ncmahl...748a"
	r, err := age.ParseX25519Recipient(recipientStr)
	if err != nil {
		log.Fatal(err)
	}

	w, err := age.Encrypt(os.Stdout, r)
	if err != nil {
		log.Fatal(err)
	}
	if _, err := io.Copy(w, os.Stdin); err != nil {
		log.Fatal(err)
	}
	_ = w.Close()
}

Код без единого выделения памяти под мегабайтные буферы: библиотека стримит внутри.

Интеграция в CI/CD

  • GitLab CI: кладём приватный ключ в CI/CD Variables (masked, protected), публичный в репо, шифруем артефакты перед upload.

  • GitHub Actions: используем actions/upload-artifact, а перед этим age -r. Secrets‑хранилище GitHub безопасно отдаёт AGE‑SECRET‑KEY.

  • Kubernetes: для initContainer шифруем конфиги, расшифровываем на поде через emptyDir. Передаём ключ через sealed-secrets или HashiCorp Vault.

Будущее проекта

В roadmap числятся:

  • Поддержка SIV‑режима AEAD для улучшения защиты от nonce‑reuse.

  • Инкрементальное шифрование для больших бэкапов.

  • Rust‑имплементация rage уже стабильна (100% совместимость формата)

Выводы

age закрыл больные места GPG там, где нужны простота, стриминг и современная криптография.


Приглашаем вас на два открытых урока курса Administrator Linux. Professional, которые помогут вам более подробно разобраться в важных аспектах администрирования Linux.

Также, если вы хотите оценить свои знания Linux, предлагаем пройти вступительное тестирование.

А чтобы узнать больше о курсах по Linux и получить доступ к записям открытых уроков, переходите в телеграм‑бот.

Комментарии (3)


  1. Squoworode
    04.08.2025 06:29

    быстро и надёжно прятать данные

    читает stdin, пишет stdout

    Большое похоже на "защищать", чем на "прятать", а прятать придётся самому...


    1. max9
      04.08.2025 06:29

      быстро и надёжно

      выберите 1 из двух :) пайпы до сих пор однопоточные


  1. CTpaHHoe
    04.08.2025 06:29

    спасибо. будет интересно попробовать сравнить по быстродействию с имеющимися средствами.

    а есть возможность расшифровать зашифрованный файл на других платформах?