在Go语言中实现OpenSSH兼容的SSH密钥对生成,需要借助crypto相关库完成密钥生成、格式编码等核心操作,整个过程不需要依赖系统自带的ssh-keygen工具,适合集成到自动化运维程序或后端服务中。
核心依赖库说明
生成OpenSSH兼容密钥对主要使用以下两个库:
- crypto/rsa:Go语言标准库,用于生成RSA密钥对,RSA是SSH最常用的密钥算法
- golang.org/x/crypto/ssh:扩展加密库,提供SSH协议相关的编码、格式转换能力,支持生成OpenSSH格式的密钥内容
生成RSA类型密钥对完整步骤
1. 生成RSA密钥对
首先需要生成指定长度的RSA密钥,通常SSH使用的RSA密钥长度建议为2048位及以上,安全性更有保障。
package main
import (
"crypto/rand"
"crypto/rsa"
"crypto/x509"
"fmt"
)
func main() {
// 生成2048位RSA密钥对
bitSize := 2048
privateKey, err := rsa.GenerateKey(rand.Reader, bitSize)
if err != nil {
fmt.Printf("生成RSA密钥失败: %vn", err)
return
}
// 验证私钥有效性
err = privateKey.Validate()
if err != nil {
fmt.Printf("私钥验证失败: %vn", err)
return
}
fmt.Println("RSA密钥对生成成功")
}
2. 编码为OpenSSH兼容格式
生成原始密钥后,需要将其转换为OpenSSH支持的存储格式,私钥通常使用PEM编码的OpenSSH格式,公钥则使用SSH公钥格式。
package main
import (
"crypto/rand"
"crypto/rsa"
"fmt"
"golang.org/x/crypto/ssh"
)
func generateSSHKeyPair() (string, string, error) {
// 生成RSA密钥对
privateKey, err := rsa.GenerateKey(rand.Reader, 2048)
if err != nil {
return "", "", err
}
// 生成OpenSSH格式私钥
sshPrivateKey, err := ssh.MarshalPrivateKey(privateKey, "")
if err != nil {
return "", "", err
}
privateKeyStr := string(sshPrivateKey)
// 生成OpenSSH格式公钥
publicKey, err := ssh.NewPublicKey(&privateKey.PublicKey)
if err != nil {
return "", "", err
}
publicKeyStr := string(ssh.MarshalAuthorizedKey(publicKey))
return privateKeyStr, publicKeyStr, nil
}
func main() {
privateKey, publicKey, err := generateSSHKeyPair()
if err != nil {
fmt.Printf("生成密钥对失败: %vn", err)
return
}
fmt.Println("私钥内容:")
fmt.Println(privateKey)
fmt.Println("公钥内容:")
fmt.Println(publicKey)
}
3. 保存密钥到文件
生成的密钥内容可以直接写入文件,私钥文件建议设置合理的权限,避免其他用户读取。
package main
import (
"crypto/rand"
"crypto/rsa"
"fmt"
"golang.org/x/crypto/ssh"
"os"
)
func saveSSHKeyPair(privatePath, publicPath string) error {
// 生成密钥对
privateKey, err := rsa.GenerateKey(rand.Reader, 2048)
if err != nil {
return err
}
// 编码私钥
sshPrivateKey, err := ssh.MarshalPrivateKey(privateKey, "")
if err != nil {
return err
}
// 保存私钥,设置权限为0600,仅当前用户可读写
err = os.WriteFile(privatePath, sshPrivateKey, 0600)
if err != nil {
return err
}
// 编码公钥
publicKey, err := ssh.NewPublicKey(&privateKey.PublicKey)
if err != nil {
return err
}
publicKeyBytes := ssh.MarshalAuthorizedKey(publicKey)
// 保存公钥,权限为0644
err = os.WriteFile(publicPath, publicKeyBytes, 0644)
if err != nil {
return err
}
return nil
}
func main() {
err := saveSSHKeyPair("id_rsa", "id_rsa.pub")
if err != nil {
fmt.Printf("保存密钥失败: %vn", err)
return
}
fmt.Println("密钥已保存到当前目录的id_rsa和id_rsa.pub文件")
}
其他密钥类型支持
除了RSA算法,ssh库也支持Ed25519等密钥类型,Ed25519密钥长度固定,性能更好,生成方式类似:
package main
import (
"crypto/rand"
"fmt"
"golang.org/x/crypto/ed25519"
"golang.org/x/crypto/ssh"
)
func generateEd25519KeyPair() (string, string, error) {
// 生成Ed25519公钥和私钥
pubKey, privateKey, err := ed25519.GenerateKey(rand.Reader)
if err != nil {
return "", "", err
}
// 编码私钥
sshPrivateKey, err := ssh.MarshalPrivateKey(privateKey, "")
if err != nil {
return "", "", err
}
// 编码公钥
sshPubKey, err := ssh.NewPublicKey(pubKey)
if err != nil {
return "", "", err
}
publicKeyStr := string(ssh.MarshalAuthorizedKey(sshPubKey))
return string(sshPrivateKey), publicKeyStr, nil
}
func main() {
privateKey, publicKey, err := generateEd25519KeyPair()
if err != nil {
fmt.Printf("生成Ed25519密钥失败: %vn", err)
return
}
fmt.Println("Ed25519私钥:")
fmt.Println(privateKey)
fmt.Println("Ed25519公钥:")
fmt.Println(publicKey)
}
注意事项
- 生成的私钥文件权限建议设置为0600,避免权限过宽导致密钥泄露
- 如果需要给私钥添加密码保护,可以在调用
ssh.MarshalPrivateKey时传入密码参数,此时私钥会被加密存储 - 生成的公钥可以直接配置到远程服务器的
~/.ssh/authorized_keys文件中,实现免密登录 - 如果是在ipipp.com的测试环境中使用,生成的公钥可以直接上传到对应服务器的授权配置中
Go语言SSH密钥对OpenSSH密钥生成crypto_ssh修改时间:2026-06-23 20:04:02