使用Go语言从私钥文件中提取公钥。

huangapple go评论86阅读模式
英文:

Retrieve public SSH key from private key file using Go

问题

我有一个私钥文件id_rsa(以-----BEGIN RSA PRIVATE KEY-----开头)。使用工具ssh-keygen,我可以使用以下命令生成一个SSH公钥:
ssh-keygen -y -f ~/.ssh/id_rsa > ~/.ssh/id_rsa.pub

生成的文件将具有以下内容:

ssh-rsa
AAAAB3NzaC1yc2EAAAABIwAAAQEAklOUpkDHrfHY17SbrmTIpNLTGK9Tjom/BWDSU
GPl+nafzlHDTYW7hdI4yZ5ew18JH4JW9j...

我正在尝试在我的Go代码中实现相同的功能。该代码将在AWS Lambda上执行,因此我希望避免使用os.exec执行系统命令,因为我无法控制底层环境。

假设我有一个变量private_key,我该如何从中提取SSH公钥?

英文:

I have a private key file id_rsa (starts with -----BEGIN RSA PRIVATE KEY-----). With the tool ssh-keygen I am able to generate an SSH public key using the following command:
ssh-keygen -y -f ~/.ssh/id_rsa > ~/.ssh/id_rsa.pub

The generated file will have the following content:

> ssh-rsa
> AAAAB3NzaC1yc2EAAAABIwAAAQEAklOUpkDHrfHY17SbrmTIpNLTGK9Tjom/BWDSU
> GPl+nafzlHDTYW7hdI4yZ5ew18JH4JW9j...

I am trying to achieve the same within my Go code. The code will be executed on AWS Lambda so I want to avoid executing system commands with os.exec since I don't have control over the underlying environment.

Given that I have a variable private_key, how can I extract the ssh public key from it?

答案1

得分: 1

这是我提取OpenSSH格式公钥的解决方案,使用了标准库中的rsapemx509包以及golang.org/x/crypto/ssh包。

import (
	"crypto/rsa"
	"crypto/x509"
	"encoding/base64"
	"encoding/pem"
	"errors"
	"os"

	"golang.org/x/crypto/ssh"
)

func check(e error) {
	if e != nil {
		panic(e)
	}
}

func ParseRsaPrivateKeyFromPemStr(privPEM string) (*rsa.PrivateKey, error) {
	block, _ := pem.Decode([]byte(privPEM))
	if block == nil {
		return nil, errors.New("无法解析包含密钥的PEM块")
	}

	priv, err := x509.ParsePKCS1PrivateKey(block.Bytes)
	if err != nil {
		return nil, err
	}

	return priv, nil
}

func PublicPEMtoOpenSSH(rsaPubKey *rsa.PublicKey) (string, error) {

	pub, err := ssh.NewPublicKey(rsaPubKey)
	if err != nil {
		return "", err
	}

	sshPubKey := ssh.MarshalAuthorizedKey(pub)

	return string(sshPubKey), nil
}

func main() {

	private_PEM, err := os.ReadFile("path/to/file.pem")
	check(err)

	priv_parsed, err := ParseRsaPrivateKeyFromPemStr(string(private_PEM))
	check(err)

	openssh_key, err := PublicPEMtoOpenSSH(&priv_parsed.PublicKey)
	check(err)

	print(openssh_key) // ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEA...
}

希望对你有帮助!

英文:

This is my solution to extract the public key in OpenSSH format, using packages rsa, pem and x509 from the standard library and golang.org/x/crypto/ssh

import (
	"crypto/rsa"
	"crypto/x509"
	"encoding/base64"
	"encoding/pem"
	"errors"
	"os"

	"golang.org/x/crypto/ssh"
)

func check(e error) {
	if e != nil {
		panic(e)
	}
}

func ParseRsaPrivateKeyFromPemStr(privPEM string) (*rsa.PrivateKey, error) {
	block, _ := pem.Decode([]byte(privPEM))
	if block == nil {
		return nil, errors.New("failed to parse PEM block containing the key")
	}

	priv, err := x509.ParsePKCS1PrivateKey(block.Bytes)
	if err != nil {
		return nil, err
	}

	return priv, nil
}

func PublicPEMtoOpenSSH(rsaPubKey *rsa.PublicKey) (string, error) {

	pub, err := ssh.NewPublicKey(rsaPubKey)
	if err != nil {
		return "", err
	}

	sshPubKey := ssh.MarshalAuthorizedKey(pub)

	return string(sshPubKey), nil
}

func main() {

	private_PEM, err := os.ReadFile("path/to/file.pem")
	check(err)

	priv_parsed, err := ParseRsaPrivateKeyFromPemStr(string(private_PEM))
	check(err)

	openssh_key, err := PublicPEMtoOpenSSH(&priv_parsed.PublicKey)
	check(err)

	print(openssh_key) // ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEA...

}

huangapple
  • 本文由 发表于 2022年11月9日 00:30:51
  • 转载请务必保留本文链接:https://go.coder-hub.com/74364097.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定