web-dev-qa-db-ja.com

暗号化された秘密鍵をgolang sshで使用する方法

暗号化されたキーをgolang sshで使用するために暗号化を解除する方法がわからないので、ポインタをいただければ幸いです。他の2つのコードソース( this oneを含む)をまとめようとしていますが、これを機能させることができません。

私はDERに到達していると思いますが、crypto/sshで使用するには、これをPEMにマーシャリングする必要があります。

-----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
}

しかし、どのようにしてDERから署名者に取得できますか?

または、これを解決する最良の方法は何ですか?

13
DazWilkin

RSA秘密鍵を含むDERブロックがある場合、x509.ParsePKCS1PrivateKeyを使用して鍵を解析し、ssh.NewSignerFromKeyを使用してssh.Signerを取得します

key, err := x509.ParsePKCS1PrivateKey(der)
if err != nil {
    log.Fatal(err)
}
signer := ssh.NewSignerFromKey(key)
7
JimB
import "golang.org/x/crypto/ssh"

暗号化されていないキーの場合:

signer, err := ssh.ParsePrivateKey(key)

暗号化されたキーで:

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

次に:

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

ここでは、ssh.ParsePrivateKey(key)を再利用できる代替手段を提供します。 decrypt関数を変更して、秘密鍵が暗号化されている場合はそれを復号化してエンコードし、それを返すようにして、返されたkeyssh.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
}
6
Madis