当前位置:网站首页>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
边栏推荐
- Deployment of JVM sandbox repeater
- 质量体系建设之路的分分合合
- Google Earth Engine(GEE)——基于 MCD64A1 的 GlobFire 日常火灾数据集
- PostgreSQLSQL高级技巧透视表
- Unity-VScode-Emmylua配置报错解决
- Microservices -- Opening
- Apachecn translation, proofreading, note sorting activity progress announcement 2022.7
- leetcode 72. Edit distance edit distance (medium)
- LOGO特训营 第二节 文字与图形的搭配关系
- Redis sentinel simply looks at the trade-offs between distributed high availability and consistency
猜你喜欢

Lost in the lock world of MySQL

Tiktok actual combat ~ the number of comments is updated synchronously

It is said that software testing is very simple, but why are there so many dissuasions?

嵌入式开发:技巧和窍门——提高嵌入式软件代码质量的7个技巧

Logo Camp d'entraînement section 3 techniques créatives initiales

蓝队攻防演练中的三段作战

sobel过滤器

Embedded development: skills and tricks -- seven skills to improve the quality of embedded software code

Introduction and application of bigfilter global transaction anti duplication component

新版判断PC和手机端代码,手机端跳转手机端,PC跳转PC端最新有效代码
随机推荐
微服务--开篇
How diff are the contents of the same configuration item in different environments?
Force buckle_ Palindrome number
【烹饪记录】--- 青椒炒千张
Convolutional neural network model -- lenet network structure and code implementation
[acwing] solution of the 58th weekly match
odps 中 对表进行了一次备份,为什么在元数据库查m_table 时,两张表的逻辑大小不一致,但数
Now MySQL cdc2.1 is parsing the datetime class with a value of 0000-00-00 00:00:00
Ascendex launched Walken (WLKN) - an excellent and leading "walk to earn" game
安装人大金仓数据库
High school physics: linear motion
制作条形码的手机App推荐
攻防世界 MISC 进阶区 can_has_stdio?
特征缩放 标准化 归一化
Éducation à la transmission du savoir | Comment passer à un test logiciel pour l'un des postes les mieux rémunérés sur Internet? (joindre la Feuille de route pour l'apprentissage des tests logiciels)
2022-07-04:以下go语言代码输出什么?A:true;B:false;C:编译错误。 package main import “fmt“ func main() { fmt.Pri
Introducing QA into the software development lifecycle is the best practice that engineers should follow
虚拟人产业面临的挑战
Naacl-22 | introduce the setting of migration learning on the prompt based text generation task
Short video system source code, click the blank space of the screen, the keyboard does not automatically stow