Golang1.7.3使用x509标准库创建自签名证书和签发名其他证书

前端之家收集整理的这篇文章主要介绍了Golang1.7.3使用x509标准库创建自签名证书和签发名其他证书前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
代码:
package rsa

import (
    "crypto/rand"
    "crypto/rsa"
    "crypto/x509"
    "crypto/x509/pkix"
    "encoding/pem"
    "io/IoUtil"
    "math/big"
    rd "math/rand"
    "os"
    "time"
)

func init() {
    rd.Seed(time.Now().UnixNano())
}

type CertInformation struct {
    Country            []string
    Organization       []string
    OrganizationalUnit []string
    EmailAddress       []string
    Province           []string
    Locality           []string
    CommonName         string
    CrtName,KeyName   string
    IsCA               bool
    Names              []pkix.AttributeTypeAndValue
}

func CreateCRT(RootCa *x509.Certificate,RootKey *rsa.PrivateKey,info CertInformation) error {
    Crt := newCertificate(info)
    Key,err := rsa.GenerateKey(rand.Reader, 2048)
    if err != nil {
        return err
    }

    var buf []byte
    if RootCa == nil || RootKey == nil {
        //创建自签名证书
        buf,err = x509.CreateCertificate(rand.Reader,Crt,&Key.PublicKey,Key)
    } else {
        //使用根证书签名
        buf,RootCa,RootKey)
    }
    if err != nil {
        return err
    }

    err = write(info.CrtName,"CERTIFICATE",buf)
    if err != nil {
        return err
    }

    buf = x509.MarshalPKCS1PrivateKey(Key)
    return write(info.KeyName,"PRIVATE KEY",buf)
}
//编码写入文件
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}
    return pem.Encode(File,b)
}

func Parse(crtPath,keyPath string) (rootcertificate *x509.Certificate,rootPrivateKey *rsa.PrivateKey,err error) {
    rootcertificate,err = ParseCrt(crtPath)
    if err != nil {
        return
    }
    rootPrivateKey,err = ParseKey(keyPath)
    return
}

func ParseCrt(path string) (*x509.Certificate,error) {
    buf,err := IoUtil.ReadFile(path)
    if err != nil {
        return nil,err
    }
    p := &pem.Block{}
    p,buf = pem.Decode(buf)
    return x509.ParseCertificate(p.Bytes)
}

func ParseKey(path string) (*rsa.PrivateKey,err
    }
    p,buf := pem.Decode(buf)
    return x509.ParsePKCS1PrivateKey(p.Bytes)
}

func newCertificate(info CertInformation) *x509.Certificate {
    return &x509.Certificate{
        SerialNumber: big.NewInt(rd.Int63()),Subject: pkix.Name{
            Country:            info.Country,Organization:       info.Organization,OrganizationalUnit: info.OrganizationalUnit,Province:           info.Province,CommonName:         info.CommonName,Locality:           info.Locality,ExtraNames:         info.Names,},NotBefore:             time.Now(),//证书的开始时间
        NotAfter:              time.Now().AddDate(20, 0, 0),//证书的结束时间
        BasicConstraintsValid: true,//基本的有效性约束
        IsCA:           info.IsCA,//是否是根证书
        ExtKeyUsage:    []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth,x509.ExtKeyUsageServerAuth},//证书用途
        KeyUsage:       x509.KeyUsageDigitalSignature | x509.KeyUsageCertSign,EmailAddresses: info.EmailAddress,}
}
测试代码:
package rsa

import (
    "crypto/x509/pkix"
    "encoding/asn1"
    "os"
    "testing"
)

func Test_crt(t *testing.T) {
    baseinfo := CertInformation{Country: []string{"CN"},Organization: []string{"WS"},IsCA: true,OrganizationalUnit: []string{"work-stacks"},EmailAddress: []string{"czxichen@163.com"},Locality: []string{"SuZhou"},Province: []string{"JiangSu"},CommonName: "Work-Stacks",CrtName: "test_root.crt",KeyName: "test_root.key"}

    err := CreateCRT(nil,nil,baseinfo)
    if err != nil {
        t.Log("Create crt error,Error info:",err)
        return
    }
    crtinfo := baseinfo
    crtinfo.IsCA = false
    crtinfo.CrtName = "test_server.crt"
    crtinfo.KeyName = "test_server.key"
    crtinfo.Names = []pkix.AttributeTypeAndValue{{asn1.ObjectIdentifier{2,1,3},"MAC_ADDR"}} //添加扩展字段用来做自定义使用

    crt,pri,err := Parse(baseinfo.CrtName,baseinfo.KeyName)
    if err != nil {
        t.Log("Parse crt error,err)
        return
    }
    err = CreateCRT(crt,crtinfo)
    if err != nil {
        t.Log("Create crt error,err)
    }
    os.Remove(baseinfo.CrtName)
    os.Remove(baseinfo.KeyName)
    os.Remove(crtinfo.CrtName)
    os.Remove(crtinfo.KeyName)
}

猜你在找的Go相关文章