03 - Passphrase
video: https://youtu.be/... no frontmatter da nota.Passphrase em Chaves SSH
1. Definição
Uma passphrase é uma senha longa, baseada em palavras reais ou frase memorável, usada para criptografar a chave privada SSH em repouso no disco do cliente. Sem a passphrase, o arquivo ~/.ssh/id_rsa (ou id_ed25519, id_ecdsa) fica em texto puro — qualquer um com acesso ao arquivo obtém a chave e pode se autenticar como o usuário. Com passphrase, o arquivo é cifrado com um algoritmo simétrico (AES-256, ChaCha20-Poly1305) e só pode ser decifrado fornecendo a passphrase correta.
A passphrase não é enviada ao servidor SSH. Ela é usada exclusivamente pelo cliente ssh para decifrar a chave privada localmente antes de usá-la no protocolo de autenticação pública. Isso é uma diferença crucial em relação a senhas tradicionais: o servidor SSH nunca vê a passphrase.
Diferenças Chave
| Conceito | Senha (password auth) | Passphrase (key auth) |
|---|---|---|
| Onde é validada | Servidor (via PAM) | Cliente (localmente) |
| Transita pela rede | Sim (dentro do canal SSH) | Não |
| Protege contra roubo de arquivo | Não (servidor tem hash) | Sim (arquivo é cifrado) |
| Pode ser brute-forceada offline | Não (rate limit servidor) | Sim (atacante com o arquivo testa livremente) |
| Automação | Trivial | Requer ssh-agent |
| Força típica | 8-12 caracteres | 20+ caracteres (frase) |
2. Estrutura do Arquivo de Chave Cifrada
Uma chave privada RSA sem passphrase é armazenada em PEM tradicional (texto Base64). Com passphrase, o cabeçalho muda para indicar o algoritmo de cifração:
Sem Passphrase (PEM legado)
-----BEGIN RSA PRIVATE KEY-----
MIIEowIBAAKCAQEAw7qVZH5QpX2v...
[base64 da chave em texto puro]
-----END RSA PRIVATE KEY-----
Com Passphrase (AES-256-CBC, formato antigo)
-----BEGIN RSA PRIVATE KEY-----
Proc-Type: 4,ENCRYPTED
DEK-Info: AES-256-CBC,ABCDEF0123456789ABCDEF0123456789
hITAyV4pZ3zVfJ7gWXhxY7n8KJc...
[base64 da chave cifrada]
-----END RSA PRIVATE KEY-----
Formato Moderno OpenSSH (bcrypt KDF)
-----BEGIN OPENSSH PRIVATE KEY-----
b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW
QyNTUxOQAAACA8YV...
-----END OPENSSH PRIVATE KEY-----
Neste formato, a chave é serializada e cifrada usando bcrypt como KDF (Key Derivation Function) com custo configurável. O parâmetro -a (rounds) do ssh-keygen controla o custo do bcrypt: -a 100 (padrão 16) torna brute-force significativamente mais caro.
3. Algoritmos de Cifração Suportados
Quando uma passphrase é aplicada, o ssh-keygen cifra a chave privada usando:
| Formato | Algoritmo | KDF | Status |
|---|---|---|---|
| PEM antigo | AES-128/256-CBC, 3DES-CBC | MD5 (fraco) | Evitar |
| PEM PKCS#8 | AES-256-CBC | PBKDF2 | Aceitável |
| OpenSSH v1 | AES-256-CTR + HMAC | bcrypt | Recomendado |
| OpenSSH v1 | ChaCha20-Poly1305 | bcrypt | Recomendado |
O formato OpenSSH v1 (default desde OpenSSH 7.8, 2018) é preferível porque usa bcrypt com custo ajustável, em vez do MD5 simples do PEM legado.
4. Geração e Gerenciamento
Gerar Chave com Passphrase
# Ed25519 (recomendado - rápido, seguro, curto)
ssh-keygen -t ed25519 -a 100 -C "joao@notebook-2024"
# RSA 4096 com KDF forte (legado, se Ed25519 não suportado)
ssh-keygen -t rsa -b 4096 -o -a 100 -C "joao@notebook-2024"
# ECDSA (alternativa)
ssh-keygen -t ecdsa -b 521 -o -a 100
A flag -o força o formato OpenSSH v1 (necessário para -a ter efeito). -a 100 aumenta o custo do bcrypt (padrão 16, máximo 63; valores altos tornam brute-force mais caro mas tornam load mais lento).
Adicionar/Remover Passphrase de Chave Existente
ssh-keygen -p -f ~/.ssh/id_ed25519
# Adiciona (se vazia) ou remove (se entrar vazio como nova) a passphrase.
# Remover passphrase NÃO é recomendado em estações compartilhadas.
Verificar Formato e Cifra
head -1 ~/.ssh/id_ed25519 # Inspecionar cabeçalho
ssh-keygen -l -f ~/.ssh/id_ed25519.pub # Detalhes da chave pública
5. ssh-agent — Cache de Passphrase
O ssh-agent é um daemon que mantém chaves privadas decifradas em memória RAM durante a sessão do usuário. Sem ele, a passphrase seria solicitada a cada conexão SSH. Com o agente, a passphrase é digitada uma única vez por sessão (ou por boot).
Ciclo de Vida
1. ssh-agent iniciado (variáveis SSH_AUTH_SOCK, SSH_AGENT_PID)
2. ssh-add ~/.ssh/id_ed25519 → pede passphrase, decifra, armazena no agente
3. ssh user@host → consulta agente via socket, assina desafio
4. Sessões subsequentes não pedem passphrase
5. ssh-add -D → remove todas as chaves do agente
6. ssh-agent -k → encerra agente (limpa memória)
Comandos Práticos
eval "$(ssh-agent -s)" # Iniciar agente
ssh-add ~/.ssh/id_ed25519 # Adicionar chave (pede passphrase)
ssh-add -l # Listar chaves carregadas
ssh-add -L # Listar fingerprints completos
ssh-add -d ~/.ssh/id_ed25519 # Remover uma chave
ssh-add -D # Remover todas
ssh-add -x # Lock do agente com senha
ssh-add -X # Destravar lock
ssh-add -t 3600 ~/.ssh/id_ed25519 # Expira em 1h
Forwarding do Agente (Agent Forwarding)
Permite que conexões SSH encadeadas usem o agente local do usuário. Útil para saltar entre servidores (ssh -A), mas perigoso: um administrador malicioso do servidor intermediário pode usar seu socket SSH_AUTH_SOCK para se autenticar como você em outros servidores.
ssh -A user@jumphost # Habilitar forwarding (cuidado!)
# Em ~/.ssh/config: ForwardAgent yes
Recomendação: usar ForwardAgent apenas em servidores sob seu controle. Em ambientes hostis, prefira ProxyJump (-J) que mantém o agente local.
6. keychain e Integração com Desktop
Em ambientes gráficos (GNOME, KDE, macOS), o agente SSH é integrado ao keyring do sistema, que desbloqueia a passphrase com a senha de login do usuário (PAM) ou com biometria. Soluções comuns:
- GNOME Keyring: autostart via
gnome-keyring-daemon --start --components=ssh. - KDE Wallet: integração similar via
kwalletd. - macOS Keychain:
ssh-add --apple-use-keychain ~/.ssh/id_ed25519armazena passphrase no Keychain. - keychain (script): utilitário que mantém agente persistente entre logins.
Configuração no macOS e keychain Linux
# ~/.ssh/config (macOS Monterey+)
Host *
UseKeychain yes
AddKeysToAgent yes
IdentityFile ~/.ssh/id_ed25519
# ~/.bashrc (Linux com keychain)
keychain --quiet ~/.ssh/id_ed25519
source ~/.keychain/$(hostname)-sh
7. Melhores Práticas de Segurança
| Prática | Recomendação |
|---|---|
| Comprimento passphrase | Mínimo 20 caracteres; ideal frase de 4+ palavras |
| Entropia | Diceware ou gerador de frases (7-8 palavras aleatórias) |
| KDF | bcrypt com -a 100 mínimo |
| Algoritmo de chave | Ed25519 (preferencial) ou RSA 4096 |
| Permissões | chmod 600 ~/.ssh/id_* (chave privada) |
| Backup | Criptografar (GPG) — nunca armazenar em claro |
| Rotação | A cada 1-2 anos ou após suspeita de vazamento |
| Compartilhamento | Nunca compartilhar chave entre usuários |
| Agente em servidor | Evitar ForwardAgent em hosts não confiáveis |
| Hardware token | YubiKey, SoloKeys via FIDO2 (ssh-keygen -t ed25519-sk) |
8. Chaves Hardware-Backed (FIDO2)
Desde OpenSSH 8.2 (2020), é possível gerar chaves Ed25519 com fator de hardware (-sk suffix). A chave privada reside em um token FIDO2 (YubiKey, SoloKeys) e nunca pode ser extraída — apenas operações de assinatura são delegadas ao token.
ssh-keygen -t ed25519-sk -C "joao@yubikey"
# Solicita toque físico no token durante a geração e a cada uso
A chave privada exportada pelo ssh-keygen é, na verdade, uma referência opaca ao token. Sem o físico, a chave é inútil — proteção contra roubo de arquivos.
9. Conclusão
A passphrase é a camada de defesa local da chave privada SSH: protege o arquivo em repouso contra roubo (laptop perdido, backup vazado, malware que copia ~/.ssh/). A combinação de formato OpenSSH v1 + bcrypt KDF + Ed25519 oferece o melhor equilíbrio entre segurança e usabilidade. O ssh-agent (com keychain/Keyring) elimina o atrito de digitar a passphrase a cada uso, mas deve ser usado com cautela em ForwardAgent. Em ambientes críticos, chaves FIDO2 (hardware-backed) eliminam completamente o risco de roubo de arquivo de chave, sendo a evolução natural para administração de produção. Nunca use chaves SSH sem passphrase em máquinas que possam ser roubadas ou acessadas por terceiros.