Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/ssh/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在golang ssh中使用加密私钥_Go_Ssh_X509 - Fatal编程技术网

如何在golang ssh中使用加密私钥

如何在golang ssh中使用加密私钥,go,ssh,x509,Go,Ssh,X509,我希望有人给我指点,因为我无法解决如何解密加密密钥以便与golang ssh一起使用。我试图将另外两个代码源(包括一个)混合在一起,但无法使其正常工作 我想我已经得到了一个DER,但需要将其重新打包到PEM,以便与crypto/ssh一起使用 -----BEGIN RSA PRIVATE KEY----- Proc-Type: 4,ENCRYPTED DEK-Info: AES-128-CBC,D7C72273BE168626E5B2D1BC72E56326 ... -----END RSA P

我希望有人给我指点,因为我无法解决如何解密加密密钥以便与golang ssh一起使用。我试图将另外两个代码源(包括一个)混合在一起,但无法使其正常工作

我想我已经得到了一个DER,但需要将其重新打包到PEM,以便与crypto/ssh一起使用

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

key, err := ioutil.ReadFile(privateKey)
if err != nil {
    log.Fatalf("Unable to read private key: %v", err)
}
使用未加密的(!)密钥,我可以:

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),
    },
}
这是可行的

我重复使用了一些代码,我认为这些代码可以让我获得解密后的PEM作为一个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
}
但是,我怎样才能从订单中找到一个签名人呢


或者,解决这个问题的最佳方法是什么?

如果您有带有RSA私钥的DER块,您可以使用
x509.ParsePKCS1PrivateKey
解析密钥,并使用
ssh.NewSignerFromKey
获取
ssh.Signer

key, err := x509.ParsePKCS1PrivateKey(der)
if err != nil {
    log.Fatal(err)
}
signer := ssh.NewSignerFromKey(key)

这里我将提供一个替代方案,它允许重用
ssh.ParsePrivateKey(key)
。我修改了
decrypt
函数,对私钥进行解密和编码(如果已加密),然后返回它,这样返回的
密钥可以直接用于
ssh.ParsePrivateKey(key)
。它利用
pem.EncodeToMemory
从解密的pem块中获取密钥

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
}
使用未加密密钥:

signer, err := ssh.ParsePrivateKey(key)
signer, err := ssh.ParsePrivateKeyWithPassphrase(key, []byte("password"))
使用加密密钥:

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


令人惊叹的。非常感谢你!我会将硬编码的{Type:“RSA私钥”,…}更改为{Type:block.Type,…},因为如果输入块不是“RSA私钥”类型,此代码段将意外更改PEM块类型。谢谢!对答案进行了更改。ParsePrivateKeyWithPassphrase()可能是包中的新添加项。如果您使用正确的包名“ssh”而不是“ssh2”,则可以实现此功能。