ca证书服务器配置,搭建ca证书服务器

本篇文章中,将描述如何使用go创建CA,并使用CA签署证书。在使用openssl创建证书时,遵循的步骤是 创建秘钥 > 创建CA > 生成要颁发证书的秘钥 > 使用CA签发证书。这种步骤,那么我们现在就来尝试下。创建证书的颁发机构#首先,会

本篇文章中,将描述如何使用go创建CA,并使用CA签署证书。在使用openssl创建证书时,遵循的步骤是 创建秘钥 > 创建CA > 生成要颁发证书的秘钥 > 使用CA签发证书。这种步骤,那么我们现在就来尝试下。

创建证书的颁发机构#

首先,会从将从创建 CA 开始。CA 会被用来签署其他证书

// 对证书进行签名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{"94016"},},NotBefore: time.Now(), // 生效时间NotAfter: time.Now().AddDate(10, 0, 0), // 过期时间 年月日IsCA: true, // 表示用于CA// openssl 中的 extendedKeyUsage = clientAuth, serverAuth 字段ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth, x509.ExtKeyUsageServerAuth}, // openssl 中的 keyUsage 字段KeyUsage: x509.KeyUsageDigitalSignature | x509.KeyUsageCertSign,BasicConstraintsValid: true,}

ca证书服务器配置,搭建ca证书服务器接下来需要对证书生成公钥和私钥

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}

我们看到的证书内容是PEM编码后的,现在caBytes我们有了生成的证书,我们将其进行 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),})

创建证书#

证书的 x509.Certificate 与CA的 x509.Certificate 属性有稍微不同,需要进行一些修改

cert:=&x509.Certificate{SerialNumber:big.NewInt(1658),Subject:pkix.Name{CommonName:"domain name",Organization:[]string{"Company,INC."},Country:[]string{"US"},Province:[]string{""},Locality:[]string{"SanFrancisco"},StreetAddress:[]string{"GoldenGateBridge"},PostalCode:[]string{"94016"},},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中的extendedKeyUsageExtKeyUsage:[]x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth,x509.ExtKeyUsageServerAuth},KeyUsage:x509.KeyUsageDigitalSignature,}

注:这里会在证书中特别添加了 DNSIP (这个不是必须的),这个选项的增加代表的我们的证书可以支持多域名

为该证书创建私钥和公钥:

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

使用CA签署证书#

有了上述的内容后,可以创建证书并用CA进行签名

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),})

把上面内容融合为一起#

创建一个 ca.go 里面是创建ca和颁发证书的逻辑

package mainimport ("bytes"cr "crypto/rand""crypto/rsa""crypto/x509""crypto/x509/pkix""encoding/pem""math/big""math/rand""net""os""time")type CERT struct {CERT []byteCERTKEY *rsa.PrivateKeyCERTPEM *bytes.BufferCERTKEYPEM *bytes.BufferCSR *x509.Certificate}funcCreateCA(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 {returnnil, err}// 对证书进行签名ca.CSR = &x509.Certificate{SerialNumber: big.NewInt(rand.Int63n(2000)),Subject: *sub,NotBefore: time.Now(), // 生效时间NotAfter: time.Now().AddDate(expire, 0, 0), // 过期时间IsCA: true, // 表示用于CA// openssl 中的 extendedKeyUsage = clientAuth, serverAuth 字段ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth, x509.ExtKeyUsageServerAuth},// openssl 中的 keyUsage 字段KeyUsage: x509.KeyUsageDigitalSignature | x509.KeyUsageCertSign,BasicConstraintsValid: true,}// 创建证书// caBytes 就是生成的证书ca.CERT, err = x509.CreateCertificate(cr.Reader, ca.CSR, ca.CSR, &ca.CERTKEY.PublicKey, ca.CERTKEY)if err != nil {returnnil, 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),})// 进行PEM编码,编码就是直接cat证书里面内容显示的东西return ca, nil}funcReq(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 {returnnil, 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 {returnnil, 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}funcWrite(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}returnnil}折叠

如果需要使用的话,可以引用这些函数

package mainimport ("crypto/x509/pkix""log""net")funcmain() {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{"94016"},}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")}

遇到的问题#

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

这里是因为 x509.CreateCertificate 的参数 privatekey 需要传入引用变量,而传入的是一个普通变量

注:x509: only RSA and ECDSA public keys supported

一些参数的意思#

extendedKeyUsage :增强型密钥用法(参见"new_oids"字段):服务器身份验证、客户端身份验证、时间戳。

extendedKeyUsage = critical,serverAuth, clientAuth, timeStamping

keyUsage: 密钥用法,防否认(nonRepudiation)、数字签名(digitalSignature)、密钥加密(keyEncipherment)。

keyUsage = nonRepudiation, digitalSignature, keyEncipherment

文章来自https://www.cnblogs.com/Cylon/p/16436126.html

以上就是小编给大家带来的关于'ca证书服务器配置,搭建ca证书服务器'的探讨分享,希望大家通过阅读小编的文章之后能够有所收获!如果大家觉得小编的文章不错的话,可以多多分享给有需要的人。

版权:本文由用户自行上传,观点仅代表作者本人,本站仅供存储服务。如有侵权,请联系管理员,了解详情>>

发布
问题