证书类似身份证,里面记录了某人的姓名、年龄、地址等个人信息,还包括这个人的公钥(身份证号码),并由认证机构(类似派出所)进行数字签名后发放,只要我们看到该证书就可以知道认证机构认定了该公钥(身份证号码)的确属于此人,解决了数字签名中无法确认是谁的公钥的问题,该证书也叫公钥证书,简称证书。
go语言生成自签证书文件(RSA)
package main
import (
"crypto/rand"
"crypto/rsa"
"crypto/x509"
"crypto/x509/pkix"
"encoding/pem"
"fmt"
"math/big"
"net"
"time"
func GenerateSelfSignedCertKey(keySize int, host string, alternateIPs []net.IP, alternateDNS []string) {
//1.生成密钥对
priv, err := rsa.GenerateKey(rand.Reader, keySize)
if err != nil {
panic(err)
//2.创建证书模板
template := x509.Certificate{
SerialNumber: big.NewInt(1), //该号码表示CA颁发的唯一序列号,在此使用一个数来代表
Issuer: pkix.Name{},
Subject: pkix.Name{CommonName: fmt.Sprintf("%s@%d", host, time.Now().Unix())},
NotBefore: time.Now(),
NotAfter: time.Now().Add(time.Hour * 24 * 365),
KeyUsage: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature | x509.KeyUsageCertSign, //表示该证书是用来做服务端认证的
ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth},
if ip := net.ParseIP(host); ip != nil {
template.IPAddresses = append(template.IPAddresses, ip)
}else {
template.DNSNames = append(template.DNSNames, host)
template.IPAddresses = append(template.IPAddresses, alternateIPs...)
template.DNSNames = append(template.DNSNames, alternateDNS...)
//3.创建证书,这里第二个参数和第三个参数相同则表示该证书为自签证书,返回值为DER编码的证书
certificate, err := x509.CreateCertificate(rand.Reader, &template, &template, &priv.PublicKey, priv)
if err != nil {
panic(err)
//4.将得到的证书放入pem.Block结构体中
block := pem.Block{
Type: "CERTIFICATE",
Headers: nil,
Bytes: certificate,
//5.通过pem编码并写入磁盘文件
file, err := os.Create("ca.crt")
if err != nil {
panic(err)
defer file.Close()
pem.Encode(file, &block)
//6.将私钥中的密钥对放入pem.Block结构体中
block = pem.Block{
Type: "RSA PRIVATE KEY",
Headers: nil,
Bytes: x509.MarshalPKCS1PrivateKey(priv),
//7.通过pem编码并写入磁盘文件
file, err = os.Create("ca.key")
if err != nil {
panic(err)
pem.Encode(file, &block)
func main(){
ip := []byte("127.0.0.1")
alternateDNS := []string{"localhost"}
GenerateSelfSignedCertKey(2048, "192.168.0.1", []net.IP{net.ParseIP(string(ip))}, alternateDNS)
}
查看证书内容
$ openssl x509 -in ca.crt -noout -text
Certificate:
Data:
Version: 3 (0x2)
Serial Number: 1 (0x1)
Signature Algorithm: sha256WithRSAEncryption
Issuer: CN = 192.168.0.1@1622130200
Validity
Not Before: May 27 15:43:20 2021 GMT
Not After : May 27 15:43:20 2022 GMT
Subject: CN = 192.168.0.1@1622130200
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
RSA Public-Key: (2048 bit)
Modulus:
00:b7:24:45:1e:1f:92:a4:19:2e:3b:76:5a:2a:39:
b6:e9:b4:a7:6f:fe:a6:a9:dd:e3:da:dd:69:46:16:
b8:d9:42:07:11:17:e8:61:b9:a8:54:07:bd:75:a1:
b5:78:82:78:48:66:ca:b6:d3:74:27:c4:06:2e:2c:
ec:69:bd:c4:2b:b3:79:6a:67:67:80:52:fc:5f:d9:
4e:32:fe:66:f7:d3:e1:8a:71:c3:0b:4b:ab:3c:e9:
e1:11:4c:7a:5a:b0:ff:87:4b:78:64:e1:ce:60:91:
71:aa:c7:d5:4e:4c:13:23:5c:25:f4:7a:aa:57:63:
77:ca:67:98:2e:5a:55:03:0d:7d:03:4b:1f:4a:31:
7a:fe:a0:16:71:d6:da:06:4e:0b:a8:b2:dd:3e:ee:
cc:08:ee:19:de:c3:a7:3b:71:2e:76:c2:40:1c:ba:
7c:b8:ed:d3:5e:b6:16:eb:88:56:a3:45:9c:a4:a4:
f5:2c:bb:d7:b6:38:34:2e:3d:48:25:ee:4e:ce:6c:
9c:ea:7f:fd:32:4f:7a:17:68:06:01:b5:bb:82:08:
bd:af:9e:39:fc:ca:4e:8e:15:48:ce:db:f7:72:c8:
4a:d9:71:97:27:f8:e7:2d:3a:af:00:0e:26:61:2f:
1c:13:27:f1:49:bf:80:b1:b9:41:14:2a:70:9e:32:
26:8b
Exponent: 65537 (0x10001)
X509v3 extensions:
X509v3 Key Usage: critical
Digital Signature, Key Encipherment, Certificate Sign
X509v3 Extended Key Usage:
TLS Web Server Authentication
X509v3 Subject Alternative Name:
DNS:localhost, IP Address:192.168.0.1, IP Address:127.0.0.1
Signature Algorithm: sha256WithRSAEncryption
a6:27:5a:75:9c:b4:b8:1b:9a:f9:fa:96:3e:3d:16:73:93:6d:
0a:d8:c1:ed:01:0c:09:0a:66:d8:f9:4d:e7:f4:93:ee:5c:c5:
e2:3c:f5:5d:06:49:50:97:86:4f:fd:c5:f5:da:aa:bd:56:b7:
0f:84:c3:18:c1:bb:4c:cb:78:14:90:13:2b:58:ae:fa:a9:2e:
2d:2d:83:f3:24:83:4a:09:54:65:a4:f3:9f:a3:65:ce:43:a0:
c4:43:f2:aa:7b:f3:f4:92:b0:6b:9b:75:ef:a3:43:cc:3d:51:
25:ec:ac:ad:b8:65:61:70:5f:c8:b6:4b:57:05:2f:95:71:9c:
e1:77:92:e1:e9:53:30:67:02:0b:c7:5c:f1:77:57:a7:09:37:
07:e4:60:0d:f5:62:c3:9d:b6:4f:fc:36:4a:c3:d4:34:9a:60:
da:9a:fd:dd:c0:3c:fd:cc:1f:06:59:a3:75:97:ad:e0:96:5e:
39:a0:e9:a2:7b:d5:54:72:e0:54:f5:a3:57:9b:89:0b:0d:a0:
fc:7c:6b:82:31:77:70:d3:a9:79:ed:db:2e:de:e7:16:a6:93:
5c:9b:b8:cc:80:5b:d8:21:4a:62:a1:8a:ce:ce:19:86:d0:b3:
fb:37:d2:74:75:3a:5d:9d:f7:0e:ff:79:0b:ae:9e:c7:df:88:
f5:6b:b2:ae
go语言生成自签证书文件(ECDSA)
package main
import (
"crypto/ecdsa"
"crypto/elliptic"
"crypto/rand"
//"crypto/rsa"
"crypto/x509"
"crypto/x509/pkix"
"encoding/pem"
"fmt"
"math/big"
"net"
"time"
func GenerateSelfSignedCertKey(keySize int, host string, alternateIPs []net.IP, alternateDNS []string) {
//1.生成密钥对
//priv, err := rsa.GenerateKey(rand.Reader, keySize)
priv, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
if err != nil {
panic(err)
//2.创建证书模板
template := x509.Certificate{
SerialNumber: big.NewInt(1), //该号码表示CA颁发的唯一序列号,在此使用一个数来代表
Issuer: pkix.Name{},
Subject: pkix.Name{CommonName: fmt.Sprintf("%s@%d", host, time.Now().Unix())},
NotBefore: time.Now(),
NotAfter: time.Now().Add(time.Hour * 24 * 365),
KeyUsage: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature | x509.KeyUsageCertSign, //表示该证书是用来做服务端认证的
ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth},
if ip := net.ParseIP(host); ip != nil {
template.IPAddresses = append(template.IPAddresses, ip)
}else {
template.DNSNames = append(template.DNSNames, host)
template.IPAddresses = append(template.IPAddresses, alternateIPs...)
template.DNSNames = append(template.DNSNames, alternateDNS...)
//3.创建证书,这里第二个参数和第三个参数相同则表示该证书为自签证书,返回值为DER编码的证书
certificate, err := x509.CreateCertificate(rand.Reader, &template, &template, &priv.PublicKey, priv)
if err != nil {
panic(err)
//4.将得到的证书放入pem.Block结构体中
block := pem.Block{
Type: "CERTIFICATE",
Headers: nil,
Bytes: certificate,
//5.通过pem编码并写入磁盘文件
file, err := os.Create("ca.crt")
if err != nil {
panic(err)
defer file.Close()
pem.Encode(file, &block)
ecpriv, err := x509.MarshalECPrivateKey(priv)
if err != nil {
panic(err)
//6.将私钥中的密钥对放入pem.Block结构体中
block = pem.Block{
Type: "ECDSA PRIVATE KEY",
Headers: nil,
//Bytes: x509.MarshalPKCS1PrivateKey(priv),
Bytes: ecpriv,
//7.通过pem编码并写入磁盘文件
file, err = os.Create("ca.key")
if err != nil {
panic(err)
pem.Encode(file, &block)
func main(){
ip := []byte("127.0.0.1")
alternateDNS := []string{"localhost"}
GenerateSelfSignedCertKey(2048, "192.168.0.1", []net.IP{net.ParseIP(string(ip))}, alternateDNS)
}
查看证书内容
$ openssl x509 -in ca.crt -noout -text
Certificate:
Data:
Version: 3 (0x2)
Serial Number: 1 (0x1)
Signature Algorithm: ecdsa-with-SHA256
Issuer: CN = 192.168.0.1@1622131917
Validity
Not Before: May 27 16:11:57 2021 GMT
Not After : May 27 16:11:57 2022 GMT
Subject: CN = 192.168.0.1@1622131917
Subject Public Key Info:
Public Key Algorithm: id-ecPublicKey
Public-Key: (256 bit)
04:7a:09:2f:ec:6b:5b:ed:c7:cd:c0:09:81:ba:d9:
e0:0d:7b:06:95:7d:34:7f:16:8b:57:32:e0:9a:49:
2c:fc:27:fe:a6:d2:1d:61:d5:aa:77:bf:77:9d:17:
dd:7a:22:9f:72:3a:d7:4d:19:f7:f7:1c:50:dd:e1:
2b:4c:7f:df:5e
ASN1 OID: prime256v1
NIST CURVE: P-256
X509v3 extensions:
X509v3 Key Usage: critical
Digital Signature, Key Encipherment, Certificate Sign
X509v3 Extended Key Usage:
TLS Web Server Authentication
X509v3 Subject Alternative Name: