Golang的TLS通信,证书文件使用.

前端之家收集整理的这篇文章主要介绍了Golang的TLS通信,证书文件使用.前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
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,}
}

猜你在找的Go相关文章