为了账号安全,请及时绑定邮箱和手机立即绑定

生成与 openssh 兼容的 ed25519 密钥对

生成与 openssh 兼容的 ed25519 密钥对

Go
达令说 2022-11-28 17:13:54
我想在 go 中使用 ed25519 生成与 openssh 兼容的 ssh 密钥来替换 rsa.GenerateKey,因为 github 不再支持它。它应该相当于:ssh-keygen -t ed25519 -C "your_email@example.com"但我找不到办法做到这一点。现在,我有这段代码: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}但似乎私钥更短,我无法解释我在 git 或 argocd 中使用它时的一些奇怪行为(有时它有效,但大多数时候无效)。-----BEGIN PRIVATE KEY-----MC4CAQAwBQYDK2VwBCIEINV+5Hyey1xTblwsVGfGmDCMdZgKQdhf1ublkGO2Qaf+-----END PRIVATE KEY-----我怎么能得到这样的结果:-----BEGIN OPENSSH PRIVATE KEY-----b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZWQyNTUxOQAAACAxIu+ndqJXpEJLk5c2qsjPvUybP8OANZlSqLaOau9ZCQAAAKCocC5dqHAu[...]AAAEChVq8FJPCYbKnNFFuISac83mzF+DDFCDrLd9Xva9fQ2zEi76d2olekQkuTlzaqyM+9TJs/w4A1mVKoto5q71kJAAAAFnlvdXJfZW1haWxAZXhhbXBsZS5jb20BAgMEBQYH-----END OPENSSH PRIVATE KEY-----
查看完整描述

1 回答

?
繁花如伊

TA贡献2012条经验 获得超12个赞

是的,我也遇到过这个。

x509包不支持ed25519所使用格式的封送处理密钥类型openssh,因此正如您所发现的,此代码 - 适用于其他密钥类型 - 对ed25519密钥失败:

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

有一个带有辅助函数edkey.MarshalED25519PrivateKey的 repo ( github.com/mikesmitty/edkey )来解决这个问题:

/* 将 ed25519 私钥写入新的 OpenSSH 私钥格式。我不知道为什么这还没有在任何地方实现,除了以 OpenSSH 私钥格式将其写入磁盘之外,您似乎可以做任何事情。*/

它似乎是仿照 openssh 来源:sshkey.c sshkey_private_to_blob2

因此,要么将该辅助函数复制到您的代码中(推荐,因为 repo 已有 5 年以上历史),要么将其作为导入引用:

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)


查看完整回答
反对 回复 2022-11-28
  • 1 回答
  • 0 关注
  • 258 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信