3 votes

Générer une paire de clés ed25519 à partir de golang

Je veux générer une clé ssh compatible avec openssh en utilisant ed25519 dans go to replace rsa.GenerateKey puisque github ne le prend plus en charge.

Cela devrait être l'équivalent de :

ssh-keygen -t ed25519 -C "your_email@example.com"

Mais je n'arrive pas à trouver un moyen de le faire.

Pour l'instant, j'ai ce code :

func GenerateSSHKeys() (*ED25519Keys, error) {
    publicKey, privateKey, err := ed25519.GenerateKey(rand.Reader)
    if err != nil {
        return nil, err
    }

    publicED25519Key, err := ssh.NewPublicKey(publicKey)

    if err != nil {
        return nil, err
    }

    pubKeyBytes := ssh.MarshalAuthorizedKey(publicED25519Key)

    bytes, err := x509.MarshalPKCS8PrivateKey(privateKey) 
    if err != nil {
        return nil, err
    }

    privBlock := pem.Block{
        Type:    "PRIVATE KEY",
        Headers: nil,
        Bytes:   bytes,
    }

    privatePEM := pem.EncodeToMemory(&privBlock)

    return &ED25519Keys{
        Public:  pubKeyBytes,
        Private: privatePEM,
    }, nil

}

Mais il semble que la clé privée soit plus courte, et je ne peux pas expliquer un comportement bizarre que j'ai en l'utilisant avec git ou argocd (parfois ça marche, mais la plupart du temps non).

-----BEGIN PRIVATE KEY-----
MC4CAQAwBQYDK2VwBCIEINV+5Hyey1xTblwsVGfGmDCMdZgKQdhf1ublkGO2Qaf+
-----END PRIVATE KEY-----

Comment puis-je me retrouver avec un truc pareil ?

-----BEGIN OPENSSH PRIVATE KEY-----
b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW
QyNTUxOQAAACAxIu+ndqJXpEJLk5c2qsjPvUybP8OANZlSqLaOau9ZCQAAAKCocC5dqHAu
[...]
AAAEChVq8FJPCYbKnNFFuISac83mzF+DDFCDrLd9Xva9fQ2zEi76d2olekQkuTlzaqyM+9
TJs/w4A1mVKoto5q71kJAAAAFnlvdXJfZW1haWxAZXhhbXBsZS5jb20BAgMEBQYH
-----END OPENSSH PRIVATE KEY-----

2voto

colminator Points 2707

Oui, j'ai rencontré ce problème également.

El x509 ne supporte pas le marshaling ed25519 dans le format utilisé par openssh Comme vous l'avez découvert, ce code - qui fonctionne avec d'autres types de clés - échoue pour ed25519 clés :

bytes, err := x509.MarshalPKCS8PrivateKey(privateKey)  // produces invalid output for ed25519 keys

Il existe un dépôt ( github.com/mikesmitty/edkey ) avec une fonction d'aide edkey.MarshalED25519PrivateKey pour y remédier :

/* Ecrit les clés privées ed25519 dans la nouvelle clé privée OpenSSH d'OpenSSH. Je n'ai aucune idée de la raison pour laquelle cela n'a pas encore été implémenté quelque part. vous pouvez tout faire sauf écrire sur le disque au format de clé privée dans le format de clé privée OpenSSH. */

il semble être modelé sur la source d'openssh : sshkey.c sshkey_private_to_blob2

Donc, soit vous copiez cette fonction d'aide dans votre code (recommandé car le repo a plus de 5 ans), soit vous la référencez en tant qu'import :

import "github.com/mikesmitty/edkey"

pubKey, privKey, _ := ed25519.GenerateKey(rand.Reader)
publicKey, _ := ssh.NewPublicKey(pubKey)

pemKey := &pem.Block{
    Type:  "OPENSSH PRIVATE KEY",
    Bytes: edkey.MarshalED25519PrivateKey(privKey),  // <- marshals ed25519 correctly
}
privateKey := pem.EncodeToMemory(pemKey)
authorizedKey := ssh.MarshalAuthorizedKey(publicKey)

_ = ioutil.WriteFile("id_ed25519", privateKey, 0600)
_ = ioutil.WriteFile("id_ed25519.pub", authorizedKey, 0644)

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X