Mensagem de erro
ssh: this private key is passphrase protected
Também aparece como
- ssh: no key found
“ssh: no key found” (listado como alias) é outra condição do mesmo analisador: os bytes não contêm nenhum bloco PEM de chave — por exemplo, uma chave pública, um arquivo `.ppk` do PuTTY ou um arquivo vazio.
golang.org/x/crypto/ssh (Go) — *ssh.PassphraseMissingError from ssh.ParsePrivateKey
O que significa
O `ssh.ParsePrivateKey` reconheceu uma chave privada criptografada e parou, porque não tem a frase secreta para descriptografá-la. O `*ssh.PassphraseMissingError` retornado traz até a chave pública, mas assinar exige a chave privada descriptografada: chame `ssh.ParsePrivateKeyWithPassphrase` ou deixe um agente SSH fazer a assinatura. O erro irmão “ssh: no key found” significa que a entrada não contém nenhuma chave reconhecível.
Por que acontece
A chave foi criada com frase secreta
comumO `ssh-keygen` pede uma frase secreta e criptografa o arquivo da chave com ela. O OpenSSH interativo pede a frase ou usa o agente; um programa em Go precisa fornecê-la explicitamente.
A ferramenta presumiu que o agente desbloquearia a chave
ocasionalEm uma estação de trabalho, o `ssh-add` mantém a chave descriptografada e o `ssh` nunca lê o arquivo. Um código Go que lê o arquivo diretamente não se beneficia do agente.
Uma chave pessoal criptografada copiada para o CI
ocasionalChaves de implantação para automação costumam ser não criptografadas e ter escopo bem restrito; reutilizar uma chave pessoal criptografada no CI falha aqui.
Como corrigir
- 1.
Detectar o erro e fornecer a frase secreta
O `errors.As` identifica a falta da frase secreta; leia a frase de um cofre de segredos, nunca do código-fonte.
go signer, err := ssh.ParsePrivateKey(keyBytes) var missing *ssh.PassphraseMissingError if errors.As(err, &missing) { passphrase := []byte(os.Getenv("SSH_KEY_PASSPHRASE")) signer, err = ssh.ParsePrivateKeyWithPassphrase(keyBytes, passphrase) } if err != nil { return err } - 2.
Assinar pelo agente SSH
Com `golang.org/x/crypto/ssh/agent`, a chave privada nunca entra no seu processo, e quem cuida da frase secreta é o agente.
go import "golang.org/x/crypto/ssh/agent" conn, err := net.Dial("unix", os.Getenv("SSH_AUTH_SOCK")) if err != nil { return err } agentClient := agent.NewClient(conn) auth := ssh.PublicKeysCallback(agentClient.Signers) // the agent holds the decrypted key