dougan4884 2017-02-08 05:32
浏览 604
已采纳

如何在Golang SSH中使用加密的私钥

I would appreciate pointers because I cannot work out how to decrypt an encrypted key in order to use it with golang ssh. I'm attempting to mash together two other sources of code (including this one) but unable to get this to work.

I think I'm getting to a DER but need to marshall this back to PEM in order to use it with crypto/ssh

-----BEGIN RSA PRIVATE KEY-----
Proc-Type: 4,ENCRYPTED
DEK-Info: AES-128-CBC,D7C72273BE168626E5B2D1BC72E56326
...
-----END RSA PRIVATE KEY-----

I read it:

key, err := ioutil.ReadFile(privateKey)
if err != nil {
    log.Fatalf("Unable to read private key: %v", err)
}

With an unencrypted (!) key, I can then:

signer, err := ssh.ParsePrivateKey(key)
if err != nil {
    log.Fatalf("Unable to parse private key: %v", err)
}

config := &ssh.ClientConfig{
    User: username,
    Auth: []ssh.AuthMethod{
        ssh.PublicKeys(signer),
    },
}

And this would work.

I reused some code that I think gets me the decrypted PEM as a DER:

func decrypt(key []byte, password []byte) []byte {
    block, rest := pem.Decode(key)
    if len(rest) > 0 {
        log.Fatalf("Extra data included in key")
    }
    der, err := x509.DecryptPEMBlock(block, password)
    if err != nil {
        log.Fatalf("Decrypt failed: %v", err)
    }
    return der
}

But, how do I get from the DER to a signer?

Or, what's the best way to solve this?

  • 写回答

3条回答 默认 最新

  • douke6027 2017-02-08 15:33
    关注

    If you have the DER block with an RSA private key, you use x509.ParsePKCS1PrivateKey to parse the key, and ssh.NewSignerFromKey to get the ssh.Signer

    key, err := x509.ParsePKCS1PrivateKey(der)
    if err != nil {
        log.Fatal(err)
    }
    signer := ssh.NewSignerFromKey(key)
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
  • drap5081683 2017-05-29 18:37
    关注

    I'm just going to provide an alternative here, which allows to reuse the ssh.ParsePrivateKey(key). I've modified the decrypt function to decrypt and encode the private key, if it is encrypted, and return it, so that the returned key can be used directly in ssh.ParsePrivateKey(key). It utilizes pem.EncodeToMemory to get the key from decrypted PEM block.

    func decrypt(key []byte, password []byte) []byte {
        block, rest := pem.Decode(key)
        if len(rest) > 0 {
            log.Fatalf("Extra data included in key")
        }
    
        if x509.IsEncryptedPEMBlock(block) {
            der, err := x509.DecryptPEMBlock(block, password)
            if err != nil {
                log.Fatalf("Decrypt failed: %v", err)
            }
            return pem.EncodeToMemory(&pem.Block{Type: block.Type, Bytes: der})
        }
        return key
    }
    
    评论
  • duannei1477 2018-06-13 09:22
    关注
    import "golang.org/x/crypto/ssh"
    

    With unencrypted key:

    signer, err := ssh.ParsePrivateKey(key)
    

    With encrypted key:

    signer, err := ssh.ParsePrivateKeyWithPassphrase(key, []byte("password"))
    

    Then:

    config := &ssh.ClientConfig{
        User: username,
        Auth: []ssh.AuthMethod{
            ssh.PublicKeys(signer),
        },
    }
    
    评论
查看更多回答(2条)

报告相同问题?

悬赏问题

  • ¥15 我现在有一些关于提升机故障的专有文本数据,量也不多,我在label studio上进行了关系和实体的标注,完成了知识图谱的构造,那么我使用生成式模型的话,我能做哪些工作来写我的论文?
  • ¥15 电脑连不上无线网络如下诊断反馈应该如何操作
  • ¥15 telegram api 使用forward_messages方法转发消息时,目标群组里面会出现此消息来源,如何隐藏?
  • ¥15 在ubuntu中无法连接到远程服务器传输文件
  • ¥15 关于#tensorflow#的问题:有没有什么方法可以让机器自己学会像素风格的图片
  • ¥15 Oracle触发器字段变化时插入指定值
  • ¥15 docker无法进入容器内部
  • ¥15 qt https 依赖openssl 静态库
  • ¥15 python flask 报错
  • ¥15 改个密码引发的项目启动问题