Как использовать зашифрованный закрытый ключ с golang ssh
Я был бы признателен указатели, потому что я не могу понять, как расшифровать зашифрованный ключ, чтобы использовать его с golang СШ. Я пытаюсь объединить два других источника кода (включая этой один), но не может получить эту работу.
Я думаю, что я добираюсь до 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
}
но как мне добраться от DER до подписывающего?
или, каков наилучший способ решить эту проблему?
3 ответов
если у вас есть блок DER с закрытым ключом RSA, вы используете 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
функция для расшифровки и кодирования закрытого ключа, если он зашифрован, и вернуть его, так что возвращается key
может использоваться непосредственно в 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
}
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),
},
}