在Golang中创建密钥和证书,与OpenSSL为本地主机所做的操作相同。

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

Create key and certificate in golang same as openssl do for local host

问题

你可以使用Go语言编写等效于以下openssl命令的代码:

package main

import (
	"crypto/rand"
	"crypto/rsa"
	"crypto/x509"
	"crypto/x509/pkix"
	"encoding/pem"
	"fmt"
	"math/big"
	"net"
	"os"
	"time"
)

func main() {
	// 生成私钥
	privateKey, err := rsa.GenerateKey(rand.Reader, 4096)
	if err != nil {
		fmt.Println("私钥生成失败:", err)
		return
	}

	// 创建证书模板
	template := x509.Certificate{
		SerialNumber: big.NewInt(1),
		Subject: pkix.Name{
			Country:            []string{""},
			Province:           []string{""},
			Organization:       []string{""},
			Locality:           []string{""},
			CommonName:         "localhost",
			OrganizationalUnit: []string{""},
		},
		NotBefore:             time.Now(),
		NotAfter:              time.Now().AddDate(10, 0, 0), // 有效期为10年
		BasicConstraintsValid: true,
		IsCA:                  true,
		KeyUsage:              x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature,
		ExtKeyUsage:           []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth},
		IPAddresses:           []net.IP{net.ParseIP("127.0.0.1")},
	}

	// 使用证书模板和私钥生成证书
	derBytes, err := x509.CreateCertificate(rand.Reader, &template, &template, &privateKey.PublicKey, privateKey)
	if err != nil {
		fmt.Println("证书生成失败:", err)
		return
	}

	// 将证书保存到文件
	certOut, err := os.Create("test.crt")
	if err != nil {
		fmt.Println("证书保存失败:", err)
		return
	}
	pem.Encode(certOut, &pem.Block{Type: "CERTIFICATE", Bytes: derBytes})
	certOut.Close()
	fmt.Println("证书已保存到 test.crt")

	// 将私钥保存到文件
	keyOut, err := os.OpenFile("test.key", os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0600)
	if err != nil {
		fmt.Println("私钥保存失败:", err)
		return
	}
	pem.Encode(keyOut, &pem.Block{Type: "RSA PRIVATE KEY", Bytes: x509.MarshalPKCS1PrivateKey(privateKey)})
	keyOut.Close()
	fmt.Println("私钥已保存到 test.key")
}

这段代码会生成一个新的证书,从证书请求中生成。生成的证书将保存在test.crt文件中,私钥将保存在test.key文件中。请确保你已经安装了Go语言环境,并且导入了必要的包。

英文:

How can I code in Go the equivalent of the following openssl command?

openssl req -subj /C=/ST=/O=/L=/CN=localhost/OU=/ -x509 -nodes -days 3650  \
-newkey rsa:4096 -keyout test.key -out test.crt

The goal is to generate a new certificate from its certificate request.

答案1

得分: 1

通过以下方式找到了解决方案:

key, err := rsa.GenerateKey(rand.Reader, 4096)
if err != nil {
    return "", "", err
}
keyBytes := x509.MarshalPKCS1PrivateKey(key)
// 私钥的PEM编码
keyPEM := pem.EncodeToMemory(
    &pem.Block{
        Type:  "RSA PRIVATE KEY",
        Bytes: keyBytes,
    },
)
fmt.Println(string(keyPEM))

notBefore := time.Now()
notAfter := notBefore.Add(365*24*10*time.Hour)

// 创建证书模板
template := x509.Certificate{
    SerialNumber:          big.NewInt(0),
    Subject:               pkix.Name{CommonName: "localhost"},
    SignatureAlgorithm:    x509.SHA256WithRSA,
    NotBefore:             notBefore,
    NotAfter:              notAfter,
    BasicConstraintsValid: true,
    KeyUsage:              x509.KeyUsageDigitalSignature | x509.KeyUsageKeyAgreement | x509.KeyUsageKeyEncipherment | x509.KeyUsageDataEncipherment,
    ExtKeyUsage:           []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth, x509.ExtKeyUsageClientAuth},
}
// 使用模板创建证书
derBytes, err := x509.CreateCertificate(rand.Reader, &template, &template, &key.PublicKey, key)
if err != nil {
    return "", "", err
}

// 证书的PEM编码
certPem := string(pem.EncodeToMemory(
    &pem.Block{
        Type:  "CERTIFICATE",
        Bytes: derBytes,
    },
))
fmt.Println(certPem)

以上是代码的翻译结果。

英文:

Found my solution by this way-

key, err := rsa.GenerateKey(rand.Reader, 4096)
if err != nil {
return "", "", err
}
keyBytes := x509.MarshalPKCS1PrivateKey(key)
// PEM encoding of private key
keyPEM := pem.EncodeToMemory(
&pem.Block{
Type:  "RSA PRIVATE KEY",
Bytes: keyBytes,
},
)
fmt.Println(string(keyPEM))
notBefore := time.Now()
notAfter := notBefore.Add(365*24*10*time.Hour)
//Create certificate templet
template := x509.Certificate{
SerialNumber:          big.NewInt(0),
Subject:               pkix.Name{CommonName: "localhost"},
SignatureAlgorithm:    x509.SHA256WithRSA,
NotBefore:             notBefore,
NotAfter:              notAfter,
BasicConstraintsValid: true,
KeyUsage:              x509.KeyUsageDigitalSignature | x509.KeyUsageKeyAgreement | x509.KeyUsageKeyEncipherment | x509.KeyUsageDataEncipherment,
ExtKeyUsage:           []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth, x509.ExtKeyUsageClientAuth},
}
//Create certificate using templet
derBytes, err := x509.CreateCertificate(rand.Reader, &template, &template, &key.PublicKey, key)
if err != nil {
return "", "", err
}
//pem encoding of certificate
certPem := string(pem.EncodeToMemory(
&pem.Block{
Type:  "CERTIFICATE",
Bytes: derBytes,
},
))
fmt.Println(certPem))

答案2

得分: 0

你可以考虑使用cloudflare/cfssl,其中包含一个cfssl.initca包,如此处所示

	var req *csr.CertificateRequest
	hostname := "cloudflare.com"
	crl := "http://crl.cloudflare.com/655c6a9b-01c6-4eea-bf21-be690cc315e0.crl" //cert_uuid.crl
	for _, param := range validKeyParams {
		for _, caconfig := range validCAConfigs {
			req = &csr.CertificateRequest{
				Names: []csr.Name{
					{
						C:  "US",
						ST: "California",
						L:  "San Francisco",
						O:  "CloudFlare",
						OU: "Systems Engineering",
					},
				},
				CN:         hostname,
				Hosts:      []string{hostname, "www." + hostname},
				KeyRequest: &param,
				CA:         &caconfig,
				CRL:        crl,
			}
			certBytes, _, keyBytes, err := New(req)
			if err != nil {
				t.Fatal("InitCA failed:", err)
			}
		}
	}
英文:

You might consider cloudflare/cfssl, which includes a cfssl.initca package, as shown here:

	var req *csr.CertificateRequest
	hostname := "cloudflare.com"
	crl := "http://crl.cloudflare.com/655c6a9b-01c6-4eea-bf21-be690cc315e0.crl" //cert_uuid.crl
	for _, param := range validKeyParams {
		for _, caconfig := range validCAConfigs {
			req = &csr.CertificateRequest{
				Names: []csr.Name{
					{
						C:  "US",
						ST: "California",
						L:  "San Francisco",
						O:  "CloudFlare",
						OU: "Systems Engineering",
					},
				},
				CN:         hostname,
				Hosts:      []string{hostname, "www." + hostname},
				KeyRequest: &param,
				CA:         &caconfig,
				CRL:        crl,
			}
			certBytes, _, keyBytes, err := New(req)
			if err != nil {
				t.Fatal("InitCA failed:", err)
			}

huangapple
  • 本文由 发表于 2021年12月7日 12:31:59
  • 转载请务必保留本文链接:https://go.coder-hub.com/70254968.html
匿名

发表评论

匿名网友

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

确定