Pular para o conteúdo
ecdsa.com

age vs GPG: criptografia de arquivos e segredos em 2026

O age faz uma só coisa: criptografa arquivos para chaves públicas curtas ou para uma frase secreta. O GnuPG implementa todo o OpenPGP, inclusive assinaturas, gerenciamento de chaves e e-mail, com toda a complexidade que isso traz.

age vs GPG é a escolha entre uma ferramenta de criptografia pequena e de propósito único e uma implementação completa do OpenPGP. O age (formato age-encryption.org/v1, especificado no C2SP) criptografa um arquivo para um ou mais destinatários — cada um deles uma string curta como age1…, uma chave pública SSH ou uma chave pós-quântica age1pq1… —, usando encapsulamento de chave com X25519 ou com ML-KEM híbrido e ChaCha20-Poly1305 para o payload. O GnuPG implementa o OpenPGP: criptografia, assinaturas, certificação, chaveiros, servidores de chaves, cartões inteligentes e integração com e-mail, com décadas de compatibilidade acumulada.

Visão geral

ageGnuPG (OpenPGP)
EscopoApenas criptografia de arquivosCriptografia, assinatura, certificação, gerenciamento de chaves
Especificaçãoage v1 (C2SP), um único formato, sem versões a negociarRFC 9580 (2024) e RFC 9980 (2026); o GnuPG segue o LibrePGP
Chave pública62 caracteres (age1…); pós-quântica, 1.959 caracteres (age1pq1…)Chave binária com IDs de usuário e autoassinaturas; 473 bytes para Ed25519 mais Cv25519 (medido)
AlgoritmosX25519, híbrido ML-KEM-768 + X25519, scrypt para frases secretas, ChaCha20-Poly1305, HKDF e HMAC-SHA-256Muitos: RSA, ECC, AES, Camellia, cifras legadas para dados antigos; ML-KEM-768 + X25519 no GnuPG 2.5
ConfiguraçãoNenhumaPreferências, modelos de confiança, configurações de algoritmo e de compressão
Texto cifrado medido para um arquivo de 26 bytes226 bytes (X25519); 1.685 bytes (pós-quântico)203 bytes (Cv25519); 1.288 bytes (subchave ML-KEM-768 + X25519)
Chaves SSH como destinatáriosSim (ssh-ed25519, ssh-rsa)Não
Chaves de hardwarePor meio de plugins: YubiKey PIV, TPM, Secure EnclaveCartões inteligentes OpenPGP e chaves de segurança
AssinaturasNenhuma, de propósitoSim
Descoberta de chavesNenhuma; os destinatários são trocados diretamenteServidores de chaves, WKD, chaveiros
Arquivos grandesProcessa em fluxo, em segmentos autenticados de 64 KiB; API de descriptografia com acesso aleatório desde a 1.3Processa em fluxo; um único pacote AEAD dividido em segmentos

O mesmo arquivo criptografado com cada um

O script abaixo criptografa um segredo de 26 bytes para um destinatário age X25519, um destinatário age pós-quântico, uma subchave Cv25519 do GnuPG e uma subchave ML-KEM-768 + X25519 do GnuPG, descriptografa cada resultado e compara os tamanhos (age 1.3.2, GnuPG 2.5.21). Tudo acontece em um diretório temporário.

age e GnuPG, clássico e pós-quântico
#!/bin/sh
dir=$(mktemp -d /tmp/agegpg.XXXXXX)   # short path: gpg-agent sockets need one
cd "$dir" || exit 1
export GNUPGHOME="$dir/g"
mkdir -m 700 g
printf 'db_password=correct-horse\n' > secret.env    # 26 bytes

echo "== age"
age-keygen -o key.txt 2> /dev/null
recipient=$(age-keygen -y key.txt)
echo "recipient: ${#recipient} characters"
age -r "$recipient" -o secret.env.age secret.env
age -d -i key.txt secret.env.age | cmp -s - secret.env && echo "decrypted: identical"
echo "ciphertext: $(wc -c < secret.env.age | tr -d ' ') bytes"

echo "== age, post-quantum recipient"
age-keygen -pq -o pq.txt 2> /dev/null
pqrecipient=$(age-keygen -y pq.txt)
echo "recipient: ${#pqrecipient} characters"
age -r "$pqrecipient" -o secret.env.pq.age secret.env
age -d -i pq.txt secret.env.pq.age | cmp -s - secret.env && echo "decrypted: identical"
echo "ciphertext: $(wc -c < secret.env.pq.age | tr -d ' ') bytes"

echo "== GnuPG"
gpg --batch --quiet --passphrase '' --quick-gen-key "Ops <ops@example.org>" ed25519 cert 1y
fpr=$(gpg --list-keys --with-colons ops@example.org 2> /dev/null | awk -F: '/^fpr/ { print $10; exit }')
gpg --batch --quiet --passphrase '' --quick-add-key "$fpr" cv25519 encr 1y
gpg --batch --quiet --trust-model always -r ops@example.org -o secret.env.gpg -e secret.env
gpg --batch --quiet -d secret.env.gpg 2> /dev/null | cmp -s - secret.env && echo "decrypted: identical"
echo "ciphertext: $(wc -c < secret.env.gpg | tr -d ' ') bytes"
echo "public key export: $(gpg --export ops@example.org | wc -c | tr -d ' ') bytes binary"

echo "== GnuPG, ML-KEM-768 + X25519 subkey"
gpg --batch --quiet --passphrase '' --quick-gen-key "Ops PQ <ops-pq@example.org>" ed25519 cert 1y
fpr=$(gpg --list-keys --with-colons ops-pq@example.org 2> /dev/null | awk -F: '/^fpr/ { print $10; exit }')
gpg --batch --quiet --passphrase '' --quick-add-key "$fpr" ky768_cv25519 encr 1y
gpg --batch --quiet --trust-model always -r ops-pq@example.org -o secret.env.pq.gpg -e secret.env
gpg --batch --quiet -d secret.env.pq.gpg 2> /dev/null | cmp -s - secret.env && echo "decrypted: identical"
echo "ciphertext: $(wc -c < secret.env.pq.gpg | tr -d ' ') bytes"
gpgconf --kill gpg-agent
cd / && rm -rf "$dir"
Saída
== age
recipient: 62 characters
decrypted: identical
ciphertext: 226 bytes
== age, post-quantum recipient
recipient: 1959 characters
decrypted: identical
ciphertext: 1685 bytes
== GnuPG
decrypted: identical
ciphertext: 203 bytes
public key export: 473 bytes binary
== GnuPG, ML-KEM-768 + X25519 subkey
decrypted: identical
ciphertext: 1288 bytes

Os dois acrescentam um cabeçalho fixo por destinatário, mais uma pequena sobrecarga de autenticação, então, em arquivos reais, a diferença é desprezível. A sobrecarga pós-quântica é o texto cifrado do ML-KEM-768 (1.088 bytes) transportado em cada bloco de destinatário; a do age é maior principalmente porque o cabeçalho dele é texto, com os valores binários em base64. O script usa --trust-model always só porque a chave foi criada um segundo antes; no uso real, você verificaria a impressão digital do destinatário.

Detalhes de interoperabilidade que importam

O gpg --list-packets aplicado aos arquivos acima mostra duas coisas que vale a pena saber. Para a chave Cv25519, o GnuPG 2.5 gravou um pacote “AEAD encrypted packet” com OCB, o formato do LibrePGP, em vez do pacote de dados criptografados versão 2 que a RFC 9580 define, porque as próprias chaves do GnuPG anunciam suporte a ele; implementações que seguem apenas a RFC 9580 podem não conseguir ler esses arquivos. Para a subchave pós-quântica, o GnuPG usou o algoritmo de chave pública 8, a variante composta com Kyber do LibrePGP, enquanto a RFC 9980 atribui o 35 ao ML-KEM-768 + X25519; por isso, as chaves pós-quânticas do GnuPG e as chaves da RFC 9980 não interoperam. O age tem um único formato e uma única construção pós-quântica (HPKE com o híbrido de ML-KEM-768 e X25519, também conhecido como X-Wing), com vetores de teste publicados.

Por que o age é pequeno de propósito

O age deixa de fora tudo o que tornava o OpenPGP difícil de usar com segurança: não há negociação de algoritmo, nem compressão (que pode vazar informações sobre o texto claro), nem modo sem autenticação, nem servidor de chaves, nem rede de confiança. Um destinatário é uma string que você pode colar em um arquivo de configuração, e um arquivo criptografado para vários destinatários tem um bloco por destinatário. O preço é o escopo: o age não tem como assinar, então não prova quem criptografou um arquivo, e não gerencia nem distribui chaves. Outras ferramentas preenchem essas lacunas em volta dele: o SOPS criptografa valores YAML e JSON para destinatários age, e plugins permitem que as identidades (chaves privadas) fiquem em YubiKeys, TPMs ou no Secure Enclave do macOS.

A abrangência é o ponto forte do GnuPG onde o OpenPGP é a língua comum: e-mail assinado e criptografado com correspondentes que já o usam, repositórios de pacotes, assinaturas de releases que os verificadores downstream já checam e cartões inteligentes OpenPGP que guardam juntas as chaves de assinatura, de criptografia e de autenticação.

Quando escolher cada um

  • Segredos no Git (SOPS), variáveis de CI, backups, dotfiles: age, com um destinatário por pessoa ou máquina e um destinatário de recuperação em hardware ou offline.
  • Criptografar para alguém cuja chave SSH você já tem: age.
  • Arquivamento confidencial de longo prazo: age com destinatários pós-quânticos age1pq1, para resistir a ataques do tipo coletar agora, descriptografar depois.
  • E-mail criptografado: OpenPGP (ou S/MIME; veja S/MIME vs OpenPGP).
  • Criptografar e assinar em uma só etapa para um destinatário que usa OpenPGP: GnuPG.
  • Assinaturas de releases e de pacotes: nenhum dos dois como ferramenta de criptografia; veja Sigstore vs GPG.

Notas de migração

  1. Gere identidades age por pessoa ou máquina (age-keygen, ou age-keygen -pq assim que todos que criptografam ou descriptografam usarem o age 1.3 ou posterior) e guarde uma identidade de recuperação offline.
  2. Recriptografe em vez de converter: descriptografe cada arquivo GPG com a chave antiga e criptografe-o para os novos destinatários; não existe conversão de formato. No SOPS, adicione os destinatários age às regras de criação em .sops.yaml e rode sops updatekeys em cada arquivo; quando depois remover as chaves PGP, rode em seguida sops rotate, para que a chave de dados também mude.
  3. Mantenha a chave GPG até que todos os arquivos e backups antigos tenham sido recriptografados ou tenham expirado.
  4. Substitua as assinaturas GPG separadamente por assinaturas SSH, minisign ou Sigstore, já que o age não oferece nenhuma.
  5. Confira tamanhos e ferramentas com a ferramenta de criptografia age e inspecione os arquivos antigos com o inspetor de OpenPGP para descobrir quais chaves e algoritmos eles usam.

Referências

Todas as comparações