跳到主要内容
ecdsa.com
golang.org/x/crypto/ssh (Go)Go

错误信息

ssh: this private key is passphrase protected

也可能输出为

  • ssh: no key found

“ssh: no key found”(列为别名)是同一个解析器报告的另一种情况:字节中没有 PEM 密钥块——例如公钥、PuTTY 的 `.ppk` 文件或空文件。

golang.org/x/crypto/ssh (Go) — *ssh.PassphraseMissingError from ssh.ParsePrivateKey

含义

`ssh.ParsePrivateKey` 识别出这是一个加密的私钥,于是停了下来,因为它没有用来解密的密码短语。返回的 `*ssh.PassphraseMissingError` 甚至携带了公钥,但签名需要解密后的私钥:调用 `ssh.ParsePrivateKeyWithPassphrase`,或者让 SSH 代理完成签名。与之相近的“ssh: no key found”则表示输入中根本没有可识别的密钥。

原因

修复方法

  1. 1.

    检测该错误并提供密码短语

    `errors.As` 可以识别出缺少密码短语的错误;从机密存储中读取密码短语,切勿从源代码中读取。

    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. 2.

    通过 SSH 代理签名

    使用 `golang.org/x/crypto/ssh/agent` 时,私钥永远不会进入你的进程,密码短语也由 SSH 代理处理。

    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

相关错误

浏览完整的签名错误库