真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

通過(guò)Go語(yǔ)言創(chuàng)建CA與簽發(fā)證書

本篇文章中,將描述如何使用go創(chuàng)建CA,并使用CA簽署證書。在使用openssl創(chuàng)建證書時(shí),遵循的步驟是 創(chuàng)建秘鑰 > 創(chuàng)建CA > 生成要頒發(fā)證書的秘鑰 > 使用CA簽發(fā)證書。這種步驟,那么我們現(xiàn)在就來(lái)嘗試下。

創(chuàng)新互聯(lián)建站專注為客戶提供全方位的互聯(lián)網(wǎng)綜合服務(wù),包含不限于網(wǎng)站建設(shè)、網(wǎng)站制作、云陽(yáng)網(wǎng)絡(luò)推廣、微信小程序、云陽(yáng)網(wǎng)絡(luò)營(yíng)銷、云陽(yáng)企業(yè)策劃、云陽(yáng)品牌公關(guān)、搜索引擎seo、人物專訪、企業(yè)宣傳片、企業(yè)代運(yùn)營(yíng)等,從售前售中售后,我們都將竭誠(chéng)為您服務(wù),您的肯定,是我們最大的嘉獎(jiǎng);創(chuàng)新互聯(lián)建站為所有大學(xué)生創(chuàng)業(yè)者提供云陽(yáng)建站搭建服務(wù),24小時(shí)服務(wù)熱線:18982081108,官方網(wǎng)址:www.cdcxhl.com

創(chuàng)建證書的頒發(fā)機(jī)構(gòu)

首先,會(huì)從將從創(chuàng)建 CA 開始。CA 會(huì)被用來(lái)簽署其他證書

// 對(duì)證書進(jìn)行簽名
ca := &x509.Certificate{
	SerialNumber: big.NewInt(2019),
	Subject: pkix.Name{
        CommonName:    "domain name",
		Organization:  []string{"Company, INC."},
		Country:       []string{"US"},
		Province:      []string{""},
		Locality:      []string{"San Francisco"},
		StreetAddress: []string{"Golden Gate Bridge"},
		PostalCode:    []string{""},
	},
	NotBefore:             time.Now(),  // 生效時(shí)間
	NotAfter:              time.Now().AddDate(10, 0, 0), // 過(guò)期時(shí)間 年月日
	IsCA:                  true, // 表示用于CA
    // openssl 中的 extendedKeyUsage = clientAuth, serverAuth 字段
	ExtKeyUsage:           []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth, x509.ExtKeyUsageServerAuth},
    // openssl 中的 keyUsage 字段
	KeyUsage:              x509.KeyUsageDigitalSignature | x509.KeyUsageCertSign,
	BasicConstraintsValid: true,
}

接下來(lái)需要對(duì)證書生成公鑰和私鑰

caPrivKey, err := rsa.GenerateKey(rand.Reader, 4096)
if err != nil {
	return err
}

然后生成證書:

caBytes, err := x509.CreateCertificate(rand.Reader, ca, ca, &caPrivKey.PublicKey, caPrivKey)
if err != nil {
	return err
}

我們看到的證書內(nèi)容是PEM編碼后的,現(xiàn)在caBytes我們有了生成的證書,我們將其進(jìn)行 PEM 編碼以供以后使用:

caPEM := new(bytes.Buffer)
pem.Encode(caPEM, &pem.Block{
	Type:  "CERTIFICATE",
	Bytes: caBytes,
})

caPrivKeyPEM := new(bytes.Buffer)
pem.Encode(caPrivKeyPEM, &pem.Block{
	Type:  "RSA PRIVATE KEY",
	Bytes: x509.MarshalPKCS1PrivateKey(caPrivKey),
})

創(chuàng)建證書

證書的 x509.Certificate 與CA的 x509.Certificate 屬性有稍微不同,需要進(jìn)行一些修改

cert := &x509.Certificate{
	SerialNumber: big.NewInt(1658),
	Subject: pkix.Name{
        CommonName:    "domain name",
		Organization:  []string{"Company, INC."},
		Country:       []string{"US"},
		Province:      []string{""},
		Locality:      []string{"San Francisco"},
		StreetAddress: []string{"Golden Gate Bridge"},
		PostalCode:    []string{""},
	},
    IPAddresses:  []net.IP{}, // 這里就是openssl配置文件中 subjectAltName 里的 IP:/IP=
    DNSNames:     []string{}, // 這里就是openssl配置文件中 subjectAltName 里的 DNS:/DNS=
	NotBefore:    time.Now(),
	NotAfter:     time.Now().AddDate(10, 0, 0),
	SubjectKeyId: []byte{1, 2, 3, 4, 6},
    // 這里就是openssl中的extendedKeyUsage 
	ExtKeyUsage:  []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth, x509.ExtKeyUsageServerAuth},
	KeyUsage:     x509.KeyUsageDigitalSignature,
}

注:這里會(huì)在證書中特別添加了 DNSIP (這個(gè)不是必須的),這個(gè)選項(xiàng)的增加代表的我們的證書可以支持多域名

為該證書創(chuàng)建私鑰和公鑰:

certPrivKey, err := rsa.GenerateKey(rand.Reader, 4096)
if err != nil {
	return err
}

使用CA簽署證書

有了上述的內(nèi)容后,可以創(chuàng)建證書并用CA進(jìn)行簽名

certBytes, err := x509.CreateCertificate(rand.Reader, cert, ca, &certPrivKey.PublicKey, caPrivKey)
if err != nil {
	return err
}

要保存成證書格式需要做PEM編碼

certPEM := new(bytes.Buffer)
pem.Encode(certPEM, &pem.Block{
	Type:  "CERTIFICATE",
	Bytes: certBytes,
})

certPrivKeyPEM := new(bytes.Buffer)
pem.Encode(certPrivKeyPEM, &pem.Block{
	Type:  "RSA PRIVATE KEY",
	Bytes: x509.MarshalPKCS1PrivateKey(certPrivKey),
})

把上面內(nèi)容融合為一起

創(chuàng)建一個(gè) ca.go 里面是創(chuàng)建ca和頒發(fā)證書的邏輯

package main

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

type CERT struct {
	CERT       []byte
	CERTKEY    *rsa.PrivateKey
	CERTPEM    *bytes.Buffer
	CERTKEYPEM *bytes.Buffer
	CSR        *x509.Certificate
}

func CreateCA(sub *pkix.Name, expire int) (*CERT, error) {
	var (
		ca  = new(CERT)
		err error
	)

	if expire < 1 {
		expire = 1
	}
	// 為ca生成私鑰
	ca.CERTKEY, err = rsa.GenerateKey(cr.Reader, 4096)
	if err != nil {
		return nil, err
	}

	// 對(duì)證書進(jìn)行簽名
	ca.CSR = &x509.Certificate{
		SerialNumber: big.NewInt(rand.Int63n(2000)),
		Subject:      *sub,
		NotBefore:    time.Now(),                       // 生效時(shí)間
		NotAfter:     time.Now().AddDate(expire, 0, 0), // 過(guò)期時(shí)間
		IsCA:         true,                             // 表示用于CA
		// openssl 中的 extendedKeyUsage = clientAuth, serverAuth 字段
		ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth, x509.ExtKeyUsageServerAuth},
		// openssl 中的 keyUsage 字段
		KeyUsage:              x509.KeyUsageDigitalSignature | x509.KeyUsageCertSign,
		BasicConstraintsValid: true,
	}
	// 創(chuàng)建證書
	// caBytes 就是生成的證書
	ca.CERT, err = x509.CreateCertificate(cr.Reader, ca.CSR, ca.CSR, &ca.CERTKEY.PublicKey, ca.CERTKEY)
	if err != nil {
		return nil, err
	}
	ca.CERTPEM = new(bytes.Buffer)
	pem.Encode(ca.CERTPEM, &pem.Block{
		Type:  "CERTIFICATE",
		Bytes: ca.CERT,
	})
	ca.CERTKEYPEM = new(bytes.Buffer)
	pem.Encode(ca.CERTKEYPEM, &pem.Block{
		Type:  "RSA PRIVATE KEY",
		Bytes: x509.MarshalPKCS1PrivateKey(ca.CERTKEY),
	})

	// 進(jìn)行PEM編碼,編碼就是直接cat證書里面內(nèi)容顯示的東西
	return ca, nil
}

func Req(ca *x509.Certificate, sub *pkix.Name, expire int, dns []string, ip []net.IP) (*CERT, error) {
	var (
		cert = &CERT{}
		err  error
	)
	cert.CERTKEY, err = rsa.GenerateKey(cr.Reader, 4096)
	if err != nil {
		return nil, err
	}
	if expire < 1 {
		expire = 1
	}
	cert.CSR = &x509.Certificate{
		SerialNumber: big.NewInt(rand.Int63n(2000)),
		Subject:      *sub,
		IPAddresses:  ip,
		DNSNames:     dns,
		NotBefore:    time.Now(),
		NotAfter:     time.Now().AddDate(expire, 0, 0),
		SubjectKeyId: []byte{1, 2, 3, 4, 6},
		ExtKeyUsage:  []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth, x509.ExtKeyUsageServerAuth},
		KeyUsage:     x509.KeyUsageDigitalSignature,
	}

	cert.CERT, err = x509.CreateCertificate(cr.Reader, cert.CSR, ca, &cert.CERTKEY.PublicKey, cert.CERTKEY)
	if err != nil {
		return nil, err
	}

	cert.CERTPEM = new(bytes.Buffer)
	pem.Encode(cert.CERTPEM, &pem.Block{
		Type:  "CERTIFICATE",
		Bytes: cert.CERT,
	})
	cert.CERTKEYPEM = new(bytes.Buffer)
	pem.Encode(cert.CERTKEYPEM, &pem.Block{
		Type:  "RSA PRIVATE KEY",
		Bytes: x509.MarshalPKCS1PrivateKey(cert.CERTKEY),
	})
	return cert, nil
}

func Write(cert *CERT, file string) error {
	keyFileName := file + ".key"
	certFIleName := file + ".crt"
	kf, err := os.Create(keyFileName)
	if err != nil {
		return err
	}
	defer kf.Close()

	if _, err := kf.Write(cert.CERTKEYPEM.Bytes()); err != nil {
		return err
	}

	cf, err := os.Create(certFIleName)
	if err != nil {
		return err
	}
	if _, err := cf.Write(cert.CERTPEM.Bytes()); err != nil {
		return err
	}
	return nil
}

如果需要使用的話,可以引用這些函數(shù)

package main

import (
	"crypto/x509/pkix"
	"log"
	"net"
)

func main() {
	subj := &pkix.Name{
		CommonName:    "chinamobile.com",
		Organization:  []string{"Company, INC."},
		Country:       []string{"US"},
		Province:      []string{""},
		Locality:      []string{"San Francisco"},
		StreetAddress: []string{"Golden Gate Bridge"},
		PostalCode:    []string{""},
	}
	ca, err := CreateCA(subj, 10)
	if err != nil {
		log.Panic(err)
	}

	Write(ca, "./ca")

	crt, err := Req(ca.CSR, subj, 10, []string{"test.default.svc", "test"}, []net.IP{})

	if err != nil {
		log.Panic(err)
	}

	Write(crt, "./tls")
}

遇到的問(wèn)題

panic: x509: unsupported public key type: rsa.PublicKey

這里是因?yàn)?x509.CreateCertificate 的參數(shù) privatekey 需要傳入引用變量,而傳入的是一個(gè)普通變量

注:x509: only RSA and ECDSA public keys supported

一些參數(shù)的意思

extendedKeyUsage :增強(qiáng)型密鑰用法(參見"new_oids"字段):服務(wù)器身份驗(yàn)證、客戶端身份驗(yàn)證、時(shí)間戳。

extendedKeyUsage = critical,serverAuth, clientAuth, timeStamping

keyUsage: 密鑰用法,防否認(rèn)(nonRepudiation)、數(shù)字簽名(digitalSignature)、密鑰加密(keyEncipherment)。

keyUsage = nonRepudiation, digitalSignature, keyEncipherment

Reference

golang ca and signed cert go

package x509


當(dāng)前題目:通過(guò)Go語(yǔ)言創(chuàng)建CA與簽發(fā)證書
瀏覽路徑:http://weahome.cn/article/dsoicpj.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部