AGE: encriptação de ficheiros sem a complexidade do GPG

Por Tiago & SkyNet · 17 de agosto de 2026

Quando me pedem para proteger um ficheiro, a resposta mais comum é o GPG. É uma ferramenta séria e continua a ser a certa em alguns cenários, mas também reconheço que se torna confusa num instante: anéis de chaves, IDs, níveis de confiança, opções que parecem não acabar e configurações espalhadas por meia dúzia de ficheiros.

O age resolve exatamente esse problema. É uma ferramenta pequena para encriptar e desencriptar ficheiros, com chaves explícitas, poucos conceitos e funcionamento feito para pipes Unix. Não tenta ser um sistema de identidade nem de assinatura digital. Faz uma coisa e faz essa coisa bem: proteger dados.

Aqui vai o que uso no dia-a-dia e porquê.

O que é o age?

O nome escreve-se em minúsculas e lê-se “age”, com o g duro. Há quem diga que é “Actually Good Encryption”, mas mais importante que o nome é a ideia: uma ferramenta de encriptação de ficheiros moderna e simples.

O age usa um modelo híbrido. Cada ficheiro recebe uma chave simétrica própria, gerada aleatoriamente. Essa chave é depois protegida para cada destinatário. Na prática, o ficheiro é cifrado com uma chave simétrica eficiente e o cabeçalho guarda uma cópia protegida dessa chave para cada receptor autorizado.

Com uma chave age normal, o esquema usa X25519 e o conteúdo é protegido com ChaCha20-Poly1305. Os ficheiros são autenticados, por isso uma alteração ao conteúdo ou ao cabeçalho faz a desencriptação falhar. O formato suporta processamento por streaming, o que permite trabalhar com pipes e ficheiros grandes sem passos intermédios.

A versão atual traz ainda chaves híbridas pós-quânticas, geradas com age-keygen -pq. São maiores, mas combinam X25519 com ML-KEM-768.

Instalação

Em Debian 12 ou superior, Ubuntu 22.04 ou superior e Arch Linux, é direto:

# Debian ou Ubuntu
sudo apt install age

# Arch Linux
sudo pacman -S age

# Fedora
sudo dnf install age

No Windows usa-se winget, no macOS o Homebrew:

winget install --id FiloSottile.age
brew install age

Há também binários pré-compilados e dá para compilar com Go. Depois de instalar, convém confirmar os dois comandos:

age --version
age-keygen --help

O age trata da encriptação e desencriptação. O age-keygen gera identidades. Nas versões mais recentes há ainda o age-inspect, que consulta metadados de um ficheiro age sem o desencriptar.

Recipients e identities

Vale a pena separar dois conceitos:

  • Um recipient é a parte pública. Serve para encriptar.
  • Uma identity é a parte privada. Serve para desencriptar.

Uma chave pública age começa normalmente por age1. A identidade correspondente começa por AGE-SECRET-KEY-1 e nunca se partilha.

É a mesma lógica de qualquer criptografia assimétrica: posso distribuir a chave pública sem problema; a privada fica num local protegido. Quem tiver a pública prepara um ficheiro para mim, mas só quem tiver a identidade privada o abre.

Gerar uma chave age

Para criar uma identidade normal:

age-keygen -o ~/.config/age/identity.txt

O ficheiro tem este aspeto (a chave, claro, é diferente):

# created: 2026-01-18T01:33:39Z
# public key: age1...
AGE-SECRET-KEY-1...

A linha public key é a que podemos partilhar. A linha AGE-SECRET-KEY é o segredo. Esse ficheiro identity.txt não vai para Git, nem para um email, nem para uma pasta de backups sem proteção.

Para obter só a chave pública a partir da identidade:

age-keygen -y ~/.config/age/identity.txt

Ou guardar o resultado num ficheiro de recipients:

age-keygen -y ~/.config/age/identity.txt > recipients.txt

E, para o futuro, as chaves híbridas pós-quânticas:

age-keygen -pq -o ~/.config/age/identity-pq.txt
age-keygen -y ~/.config/age/identity-pq.txt > recipient-pq.txt

Atenção: a opção pós-quântica não se mistura com chaves clássicas no mesmo ficheiro. Se o objetivo é proteção pós-quântica, todos os recipients desse ficheiro têm de ser desse tipo.

Encriptar um ficheiro com uma chave pública

O caso normal:

age \
  --recipient age1chave-publica-do-destinatario \
  --output documento.pdf.age \
  documento.pdf

A versão curta é mais compacta:

age -r age1chave-publica-do-destinatario -o documento.pdf.age documento.pdf

O original não é apagado. O age cria documento.pdf.age, que só abre com a identidade correspondente.

Também dá para usar a saída padrão, útil em scripts:

age -r age1chave-publica-do-destinatario documento.pdf > documento.pdf.age

Desencriptar um ficheiro

Para abrir o ficheiro com a identidade que criámos:

age \
  --decrypt \
  --identity ~/.config/age/identity.txt \
  --output documento-aberto.pdf \
  documento.pdf.age

Ou, com as opções curtas:

age -d -i ~/.config/age/identity.txt -o documento-aberto.pdf documento.pdf.age

Uma identidade pode conter várias chaves. Posso indicar vários ficheiros com -i; o age tenta cada um até encontrar um que corresponda a um recipient do ficheiro.

Encriptação com password

Quando não apetece gerir um par de chaves, uma password chega:

age --passphrase --output segredo.txt.age segredo.txt

A forma curta:

age -p segredo.txt > segredo.txt.age

O programa pede a password no terminal. Se a deixarmos vazia, o age pode gerar uma passphrase segura sozinho. Para desencriptar não é preciso -i:

age --decrypt --output segredo.txt segredo.txt.age

Isto é prático para enviar um ficheiro a alguém quando se consegue passar a password por outro canal. Não se envia o ficheiro e a password na mesma mensagem, e não se colocam passwords na linha de comandos (ficam no histórico da shell).

Usar vários destinatários

Um dos pormenores mais úteis do age é encriptar o mesmo ficheiro para várias pessoas ou máquinas:

age \
  -r age1chave-do-tiago \
  -r age1chave-do-servidor \
  -r age1chave-da-ci \
  -o configuracao.tar.gz.age \
  configuracao.tar.gz

Cada destinatário desencripta com a sua própria identidade. Não há password comum a partilhar.

Quando a lista cresce, um ficheiro ajuda:

# equipa de administração
age1chave-da-equipa

# servidor de backup
age1chave-do-backup

E depois:

age -R recipients.txt -o backup.tar.gz.age backup.tar.gz

Linhas vazias e comentários a começar por # são ignorados.

Usar chaves SSH

Se já temos chaves SSH, o age usa-as por conveniência. Suporta chaves públicas ssh-ed25519 e ssh-rsa. Para encriptar com a pública:

age -R ~/.ssh/id_ed25519.pub -o documento.pdf.age documento.pdf

Para desencriptar, com a privada:

age -d -i ~/.ssh/id_ed25519 -o documento.pdf documento.pdf.age

Confesso que prefiro chaves age nativas quando desenho um sistema novo. As chaves SSH têm outros ciclos de vida, são substituídas, servem para autenticação. Ainda assim, esta opção é muito útil quando já há infraestrutura SSH e não faz sentido criar mais um par de chaves só para uma tarefa pontual.

O ssh-agent não é usado para desencriptar. O age precisa do ficheiro da chave privada e, se estiver protegido, pede a password na hora.

--armor: quando é preciso texto ASCII

O formato normal é binário. Para atravessar sistemas que só aceitam texto, há o ASCII armor:

age -a -r age1chave-publica -o segredo.age.txt segredo.txt

O resultado começa por:

-----BEGIN AGE ENCRYPTED FILE-----

Para desencriptar, o age deteta este formato sozinho:

age -d -i ~/.config/age/identity.txt segredo.age.txt > segredo.txt

Para backups e ficheiros locais fico pelo binário. O armor aumenta o tamanho e só compensa quando o ficheiro vai passar por um canal que não lida bem com dados binários.

Pipes: o que torna o age interessante

Como o age aceita entrada e saída standard, encaixa que nem uma luva nas ferramentas Unix.

Encriptar uma pasta

O age encripta ficheiros, não pastas. Para uma pasta, criamos um tarball e enviamo-lo direto para o age:

tar -czf - ~/Documentos | \
  age -r age1chave-do-backup > documentos.tar.gz.age

Para restaurar:

age -d -i ~/.config/age/identity.txt documentos.tar.gz.age | \
  tar -xzf -

Nem precisamos de um documentos.tar.gz desprotegido no disco.

Encriptar uma base de dados exportada

pg_dump nome_da_base_de_dados | \
  age -r age1chave-do-backup > base-de-dados.sql.age

Para importar:

age -d -i ~/.config/age/identity.txt base-de-dados.sql.age | \
  psql nome_da_base_de_dados

O mesmo padrão vale para mysqldump, ficheiros de configuração, exportações e logs com informação sensível.

Casos de uso reais

Backups para um disco ou cloud

Um backup não deixa de ser sensível por estar num disco externo ou na cloud. Proteger antes de copiar:

tar -czf - ~/dados-importantes | \
  age -r age1chave-do-backup > dados-$(date +%F).tar.gz.age

Depois sincronizo só o .age com rsync, rclone ou outro cliente. O serviço vê um ficheiro opaco; a chave privada fica comigo.

Para backups automáticos, a identidade privada nunca entra no script. O script só precisa da pública para encriptar. A privada só é precisa ao restaurar. Isto reduz bastante o impacto se uma máquina de backup for comprometida.

Ficheiros .env e segredos de aplicações

Em vez de mandar um .env por mensagens ou guardar credenciais num repositório:

age -r age1chave-do-deploy -o .env.age .env

O .env original continua no .gitignore:

.env

O .env.age pode ser versionado, desde que a chave privada não vá para o Git. No servidor, o deploy desencripta no momento certo:

age -d -i /etc/myapp/age-identity.txt .env.age > .env
chmod 600 .env

Para YAML, JSON ou .env onde só alguns campos devem ficar protegidos, o age sozinho cifra o ficheiro inteiro. A combinação habitual é usar SOPS com age, que mantém a estrutura e cifra só os valores escolhidos. Muito útil em configurações versionadas e pipelines de CI.

Enviar um documento por email

Encripto o documento para a chave pública do destinatário e mando o .age como anexo:

age -r age1chave-publica-do-destinatario \
  -o fatura.pdf.age fatura.pdf

A chave privada nunca sai das mãos do destinatário. Se usar password, envio-a por chamada ou outro canal, nunca na mesma mensagem do anexo.

Partilhar um ficheiro com o meu computador e um servidor

Simples e muito útil. Encripto para os dois recipients:

age -r age1chave-do-computador \
    -r age1chave-do-servidor \
    -o configuracao.tar.gz.age configuracao.tar.gz

Não copio a minha identidade privada para o servidor. Cada máquina mantém a sua.

Comandos e opções mais importantes

Opção Função
-e, --encrypt Encripta a entrada. Comportamento por defeito.
-d, --decrypt Desencripta a entrada.
-r, --recipient Encripta para uma chave pública. Pode repetir-se.
-R, --recipients-file Lê recipients de um ficheiro, um por linha.
-p, --passphrase Encripta com uma password pedida no terminal.
-i, --identity Usa uma identidade privada para desencriptar. Pode repetir-se.
-o, --output Define o ficheiro de saída. Sem esta opção, usa stdout.
-a, --armor Usa o formato ASCII armor em vez do binário.
--version Mostra a versão instalada.

Para a ajuda completa no sistema:

age --help
man age
age-keygen --help

E para inspecionar um ficheiro sem o abrir:

age-inspect --json ficheiro.age

O age-inspect mostra formato, recipients e tamanho do payload, mas não revela o conteúdo.

O que o age não faz

O age não assina. Encriptação e assinatura são problemas diferentes. Se precisamos de provar quem criou ou assinou um ficheiro, usamos outra ferramenta.

Também não é um gestor de chaves. Não há rede de confiança, servidor de chaves ou base de dados central. É intencional e torna o programa mais previsível, mas obriga-nos a guardar as identidades e a distribuir as chaves públicas com cuidado.

Perder a identidade privada é perder o acesso aos ficheiros. Não há recuperação automática. Para dados importantes, a identidade merece uma cópia protegida, idealmente num password manager ou noutro suporte offline seguro.

E encriptar não resolve tudo. O nome do ficheiro, os tamanhos, as datas e o local onde o .age é guardado continuam visíveis. E, depois de desencriptar, o ficheiro volta a existir em claro no sistema.

Boas práticas

  1. Guarda a identidade privada com permissões restritas:

    chmod 600 ~/.config/age/identity.txt
  2. Não metas identidades privadas em Git, scripts, imagens Docker ou ficheiros de configuração públicos.

  3. Usa recipients separados para pessoas, computadores, servidores e CI.

  4. Para backups, encripta antes do upload e testa regularmente a restauração.

  5. Não envies a password pelo mesmo canal que o ficheiro.

  6. Não uses age como substituto universal de assinaturas ou de um gestor de segredos.

  7. Quando uma chave deixa de ser confiável, volta a encriptar os ficheiros para um recipient novo. O age não faz rotação de recipients num ficheiro já criado.

AGE ou GPG?

Não vejo o age como uma tentativa de apagar o GPG do mapa. O GPG tem uma história longa, integrações com OpenPGP, assinaturas e uma rede de chaves que o age não pretende substituir.

Para encriptar ficheiros locais, backups, exportações de bases de dados ou segredos de aplicações, o age é normalmente mais fácil de explicar e automatizar. Há menos estados escondidos e os comandos dizem claramente para quem o ficheiro é encriptado.

Se preciso de compatibilidade com OpenPGP, assinaturas ou uma infraestrutura de chaves GPG, continuo com o GPG. Se só preciso de pegar num ficheiro e garantir que mais ninguém o lê, começo pelo age.

Conclusão

O age não tenta impressionar com uma lista interminável de funcionalidades. Essa é precisamente uma das suas vantagens. Geramos uma identidade, distribuímos a pública, encriptamos com -r, desencriptamos com -i e usamos pipes quando precisamos de encaixar a ferramenta num script ou num backup.

Para quem vive no terminal e quer proteger ficheiros sem montar uma pequena burocracia à volta das chaves, é uma opção muito prática. Não elimina a necessidade de pensar na gestão das chaves, mas torna o funcionamento simples o suficiente para que seja mais difícil fazer asneira por engano.


Projeto: FiloSottile/age · Especificação do formato v1.

Tags: #Linux #segurança #criptografia #age