..

generating ed25519 ssh deploy keys in Go

Sharing with others, hoping it will help someone else someday.

The task was to generate Ed25519 specific SSH keypairs in Go for the purpose of being used as deploy keys.

Using ssh-keygen gets you a PEM-encoded private key and a correctly encoded public key. You don’t get the same when using the crypto/ed25519 package.

Let us begin by first correctly encoding the public key.

type Key struct {
	PublicKey                ed25519.PublicKey
	PrivateKey               ed25519.PrivateKey
	PublicKeyEncodedToString string
}

func GenerateEd25519Keys() (*Key, error) {

	const sshAlgoType = "ssh-ed25519"

	pubKey, privKey, err := ed25519.GenerateKey(rand.Reader)


	pubPublicKey, err := ssh.NewPublicKey(pubKey)

  // pubPublicKey is not encoded in the correct format a typical VCS requires.
  //  - does not include the `ssh-ed25519` prefix
  // Here we prefix the public key with the algorithm type.
	sshPubKey := sshAlgoType + " " + base64.StdEncoding.EncodeToString(pubPublicKey.Marshal())

	return &Key{
		PublicKey:                pubKey,
		PublicKeyEncodedToString: sshPubKey,
		PrivateKey:               privKey,
	}, nil
}

Next, we PEM encode the private key. This is the same as the private key generated by ssh-keygen.

func PrivateKeyToPEM(privKey ed25519.PrivateKey) ([]byte, error) {
	keybytes, _ := x509.MarshalPKCS8PrivateKey(privKey)

	keyBuf := &bytes.Buffer{}
	err := pem.Encode(keyBuf, &pem.Block{Type: "PRIVATE KEY", Bytes: keybytes})

	return keyBuf.Bytes(), err
}

Play with this code via Go Playground.