当前位置:网站首页>Create Ca and issue certificate through go language
Create Ca and issue certificate through go language
2022-07-04 22:40:00 【Hermokrates】
In this article , Will describe how to use go establish CA, And use CA Signed certificate . In the use of openssl When creating a certificate , The steps to follow are Create secret key > establish CA > Generate the secret key to issue the certificate > Use CA grant a certificate . Such steps , So let's try it now .
The authority that created the certificate
First , Will be created from CA Start .CA Will be used to sign other certificates
// Sign the certificate
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(), // entry-into-force time
NotAfter: time.Now().AddDate(10, 0, 0), // Expiration time Specific date
IsCA: true, // For CA
// openssl Medium extendedKeyUsage = clientAuth, serverAuth Field
ExtKeyUsage: []x509.ExtKeyUsage{
x509.ExtKeyUsageClientAuth, x509.ExtKeyUsageServerAuth},
// openssl Medium keyUsage Field
KeyUsage: x509.KeyUsageDigitalSignature | x509.KeyUsageCertSign,
BasicConstraintsValid: true,
}
Next, you need to generate public and private keys for the certificate
caPrivKey, err := rsa.GenerateKey(rand.Reader, 4096)
if err != nil {
return err
}
And then generate the certificate :
caBytes, err := x509.CreateCertificate(rand.Reader, ca, ca, &caPrivKey.PublicKey, caPrivKey)
if err != nil {
return err
}
The certificate we see is PEM Encoding , Now? caBytes We have the generated certificate , We'll do it PEM Code for later use :
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),
})
Create certificate
Certificate x509.Certificate And CA Of x509.Certificate Properties are slightly different , Some changes are needed
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{
"94016"},
},
IPAddresses: []net.IP{
}, // Here is the openssl In profile subjectAltName Inside IP:/IP=
DNSNames: []string{
}, // Here is the openssl In profile subjectAltName Inside DNS:/DNS=
NotBefore: time.Now(),
NotAfter: time.Now().AddDate(10, 0, 0),
SubjectKeyId: []byte{
1, 2, 3, 4, 6},
// Here is the openssl Medium extendedKeyUsage
ExtKeyUsage: []x509.ExtKeyUsage{
x509.ExtKeyUsageClientAuth, x509.ExtKeyUsageServerAuth},
KeyUsage: x509.KeyUsageDigitalSignature,
}
notes : Here, the certificate will be specially added
DNSandIP( This is not necessary ), The addition of this option means that our certificate can support multiple domain names
Create a private and public key for the certificate :
certPrivKey, err := rsa.GenerateKey(rand.Reader, 4096)
if err != nil {
return err
}
Use CA Signed certificate
With the above content , You can create certificates and use CA To sign
certBytes, err := x509.CreateCertificate(rand.Reader, cert, ca, &certPrivKey.PublicKey, caPrivKey)
if err != nil {
return err
}
To save in certificate format, you need to do PEM code
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),
})
Integrate the above contents
Create a ca.go Inside is create ca And the logic of issuing certificates
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
}
// by ca Generate private key
ca.CERTKEY, err = rsa.GenerateKey(cr.Reader, 4096)
if err != nil {
return nil, err
}
// Sign the certificate
ca.CSR = &x509.Certificate{
SerialNumber: big.NewInt(rand.Int63n(2000)),
Subject: *sub,
NotBefore: time.Now(), // entry-into-force time
NotAfter: time.Now().AddDate(expire, 0, 0), // Expiration time
IsCA: true, // For CA
// openssl Medium extendedKeyUsage = clientAuth, serverAuth Field
ExtKeyUsage: []x509.ExtKeyUsage{
x509.ExtKeyUsageClientAuth, x509.ExtKeyUsageServerAuth},
// openssl Medium keyUsage Field
KeyUsage: x509.KeyUsageDigitalSignature | x509.KeyUsageCertSign,
BasicConstraintsValid: true,
}
// Create certificate
// caBytes Is the generated certificate
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),
})
// Conduct PEM code , Coding is direct cat What is shown in the certificate
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
}
If needed , You can reference these functions
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{
"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")
}
Problems encountered
panic: x509: unsupported public key type: rsa.PublicKey
This is because x509.CreateCertificate Parameters of privatekey You need to pass in reference variables , What is passed in is a common variable
notes :x509: only RSA and ECDSA public keys supported
The meaning of some parameters
extendedKeyUsage : Enhanced key usage ( See "new_oids" Field ): Server authentication 、 Client authentication 、 Time stamp .
extendedKeyUsage = critical,serverAuth, clientAuth, timeStamping
keyUsage : Key usage , Anti denial (nonRepudiation)、 digital signature (digitalSignature)、 Key encryption (keyEncipherment).
keyUsage = nonRepudiation, digitalSignature, keyEncipherment
Reference
边栏推荐
- PostgreSQL server programming aggregation and grouping
- Redis sentinel simply looks at the trade-offs between distributed high availability and consistency
- LOGO特訓營 第一節 鑒別Logo與Logo設計思路
- Alibaba launched a new brand "Lingyang" and is committed to becoming a "digital leader"
- Force buckle_ Palindrome number
- Shell script implements application service log warehousing MySQL
- LOGO特訓營 第三節 首字母創意手法
- 2022-07-04: what is the output of the following go language code? A:true; B:false; C: Compilation error. package main import “fmt“ func main() { fmt.Pri
- 9 - 类
- LOGO special training camp section I identification logo and Logo Design Ideas
猜你喜欢

Tla+ introductory tutorial (1): introduction to formal methods

2022-07-04: what is the output of the following go language code? A:true; B:false; C: Compilation error. package main import “fmt“ func main() { fmt.Pri

Mongodb aggregation operation summary

Business is too busy. Is there really no reason to have time for automation?

Unity修仙手游 | lua动态滑动功能(3种源码具体实现)

Co create a collaborative ecosystem of software and hardware: the "Joint submission" of graphcore IPU and Baidu PaddlePaddle appeared in mlperf

Common open source codeless testing tools

Convolutional neural network model -- lenet network structure and code implementation
Redis sentinel simply looks at the trade-offs between distributed high availability and consistency

新版判断PC和手机端代码,手机端跳转手机端,PC跳转PC端最新有效代码
随机推荐
微服务--开篇
Redis的持久化机制
About stack area, heap area, global area, text constant area and program code area
Common open source codeless testing tools
关于栈区、堆区、全局区、文字常量区、程序代码区
Hit the core in the advanced area of misc in the attack and defense world
Apachecn translation, proofreading, note sorting activity progress announcement 2022.7
Jvm-Sandbox-Repeater的部署
[the 2023 autumn recruitment of MIHA tour] open [the only exclusive internal push code of school recruitment eytuc]
测试必会:BUG的分类及推进解决
Short video system source code, click the blank space of the screen, the keyboard does not automatically stow
MYSQL架构——用户权限与管理
Postgresqlql advanced skills pivot table
Flask 上下文详解
10 schemes to ensure interface data security
Attack and defense world misc advanced grace-50
Interview essential leetcode linked list algorithm question summary, whole process dry goods!
30余家机构联合发起数字藏品行业倡议,未来会如何前进?
The sandbox has reached a cooperation with digital Hollywood to accelerate the economic development of creators through human resource development
Tla+ introductory tutorial (1): introduction to formal methods