package main
import (
"crypto/rand"
"crypto/rsa"
"crypto/x509"
"crypto/x509/pkix"
"encoding/pem"
"io/IoUtil"
"math/big"
"os"
"time"
)
func main() {
info := CertInformation{Country: []string{"中国"},Organization: []string{"游戏蜗牛"},OrganizationalUnit: []string{"blog.csdn.net/fyxichen"},EmailAddress: []string{"czxichen@163.com"},StreetAddress: []string{"中心大道西171"},Province: []string{"江苏省·工业园区"},SubjectKeyId: []byte{1,2,3,4,5,6},Certificate: "client.crt",PrivateKey: "client.key",ROOTCertificate: "server.pem",ROOTPrivateKey: "server.key"}
err := CreateCerts(info)
if err != nil {
println(err.Error())
}
}
type CertInformation struct {
Country []string
Organization []string
OrganizationalUnit []string
EmailAddress []string
Province []string
StreetAddress []string
SubjectKeyId []byte
Certificate string
PrivateKey string
ROOTCertificate string
ROOTPrivateKey string
}
func CreateCerts(info CertInformation) error {
var rootPrivateKey *rsa.PrivateKey
var rootcertificate *x509.Certificate
var err error
ca := newCertificate(info)
priv,_ := rsa.GenerateKey(rand.Reader,2048)
//读取根证书
if info.Certificate != "" && info.PrivateKey != "" {
rootcertificate,rootPrivateKey,err = parseCerts(info.ROOTCertificate,info.ROOTPrivateKey)
if os.IsNotExist(err) {
rootPrivateKey,_ = rsa.GenerateKey(rand.Reader,2048)
rootcertificate = ca
ca_b,err := x509.CreateCertificate(rand.Reader,rootcertificate,&rootPrivateKey.PublicKey,rootPrivateKey)
if err != nil {
return err
}
err = write(info.ROOTCertificate,"CERTIFICATE",ca_b)
if err != nil {
return err
}
priv_b := x509.MarshalPKCS1PrivateKey(rootPrivateKey)
err = write(info.ROOTPrivateKey,"PRIVATE KEY",priv_b)
if err != nil {
return err
}
} else if err != nil {
return err
}
} else {
rootcertificate = ca
rootPrivateKey = priv
}
ca_b,ca,&priv.PublicKey,rootPrivateKey)
if err != nil {
return err
}
err = write(info.Certificate,ca_b)
if err != nil {
return err
}
priv_b := x509.MarshalPKCS1PrivateKey(priv)
err = write(info.PrivateKey,priv_b)
if err != nil {
return err
}
return nil
}
func write(filename,Type string,p []byte) error {
File,err := os.Create(filename)
defer File.Close()
if err != nil {
return err
}
var b *pem.Block = &pem.Block{Bytes: p,Type: Type}
err = pem.Encode(File,b)
if err != nil {
return err
}
return nil
}
func parseCerts(ROOTCertificate,ROOTPrivateKey string) (*x509.Certificate,*rsa.PrivateKey,error) {
var rootPrivateKey *rsa.PrivateKey
var rootcertificate *x509.Certificate
buf,err := IoUtil.ReadFile(ROOTCertificate)
if err != nil {
return nil,nil,err
}
p := &pem.Block{}
p,buf = pem.Decode(buf)
rootcertificate,err = x509.ParseCertificate(p.Bytes)
if err != nil {
return nil,err
}
buf,err = IoUtil.ReadFile(ROOTPrivateKey)
if err != nil {
return nil,err
}
p,buf = pem.Decode(buf)
rootPrivateKey,err = x509.ParsePKCS1PrivateKey(p.Bytes)
if err != nil {
return nil,err
}
return rootcertificate,nil
}
func newCertificate(info CertInformation) *x509.Certificate {
return &x509.Certificate{
SerialNumber: big.NewInt(1653),Subject: pkix.Name{
Country: info.Country,Organization: info.Organization,OrganizationalUnit: info.OrganizationalUnit,Province: info.Province,StreetAddress: info.StreetAddress,},NotBefore: time.Now(),NotAfter: time.Now().AddDate(10,0),SubjectKeyId: info.SubjectKeyId,BasicConstraintsValid: true,IsCA: true,ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth,x509.ExtKeyUsageServerAuth},KeyUsage: x509.KeyUsageDigitalSignature | x509.KeyUsageCertSign,EmailAddresses: info.EmailAddress,}
}
原文链接:https://www.f2er.com/go/189824.html