go语言生成自签证书文件(SM2)
package mainimport ( "crypto/rand" "crypto/x509/pkix" "encoding/pem" "github.com/tjfoc/gmsm/sm2" "github.com/tjfoc/gmsm/x509" "math/big" "net" "os" "time")func GenerateCertKeySM2(host, commonName string, alternateIPs []net.IP, alternateDNS []string){ priv, err := sm2.GenerateKey(rand.Reader) if err != nil { panic(err) } max := new(big.Int).Lsh(big.NewInt(1), 128) serialNumber, _ := rand.Int(rand.Reader, max) template := x509.Certificate{ SerialNumber: serialNumber, Issuer: pkix.Name{}, Subject: pkix.Name{ CommonName: commonName, Organization: []string{"Test"}, Country: []string{"CN"}, ExtraNames: []pkix.AttributeTypeAndValue{ { Type: []int{2, 5, 4, 42}, Value: "Gopher", }, { Type: []int{2, 5, 4, 6}, Value: "NL", }, }, }, NotBefore: time.Now(), NotAfter: time.Now().Add(time.Hour * 24 * 365), KeyUsage: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature | x509.KeyUsageCertSign, BasicConstraintsValid: true, IsCA: true, SignatureAlgorithm: x509.SM2WithSM3, } 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...) publicKey := priv.Public().(*sm2.PublicKey) certificateToPem, err := x509.CreateCertificateToPem(&template, &template, publicKey, priv) if err != nil { panic(err) } file, err := os.Create("caSM2.crt") if err != nil { panic(err) } defer file.Close() file.Write(certificateToPem) privateKey, err := x509.MarshalSm2PrivateKey(priv, []byte("jjjjjj")) if err != nil { panic(err) } block := pem.Block{ Type: "SM2 PRIVATE KEY", Headers: nil, Bytes: privateKey, } file, err = os.Create("caSM2.key") if err != nil { panic(err) } defer file.Close() err = pem.Encode(file, &block) if err != nil { panic(err) }}func main(){ ip := []byte("127.0.0.1") alternateDNS := []string{"localhost"} GenerateCertKeySM2("192.168.0.1", "www.example.com", []net.IP{net.ParseIP(string(ip))}, alternateDNS)}
查看证书信息,用该库生成的证书Signature Algorithm字段解析进去的值与template中设置的不统一,已在GitHub提交了issue
$ openssl x509 -in caSM2.crt -noout -textCertificate: Data: Version: 3 (0x2) Serial Number: ed:e3:0a:34:c5:8f:49:09:13:e4:7b:77:ec:45:87:c8 Signature Algorithm: 1.2.156.10197.1.501 Issuer: O = Test, CN = www.example.com, GN = Gopher, C = NL Validity Not Before: May 28 13:20:58 2021 GMT Not After : May 28 13:20:58 2022 GMT Subject: O = Test, CN = www.example.com, GN = Gopher, C = NL Subject Public Key Info: Public Key Algorithm: id-ecPublicKey Public-Key: (256 bit) pub: 04:85:a3:bf:57:67:23:40:fb:81:c4:3f:14:c9:96: 31:a7:76:68:2b:c7:2b:56:b4:9d:3e:f8:9b:69:ff: 97:60:97:97:5d:09:ad:fe:95:28:d1:75:59:bf:00: f8:cb:8f:27:d9:af:4d:4d:57:07:d8:dd:20:a7:eb: d0:6e:2d:25:8f ASN1 OID: SM2 X509v3 extensions: X509v3 Key Usage: critical Digital Signature, Key Encipherment, Certificate Sign X509v3 Basic Constraints: critical CA:TRUE X509v3 Subject Alternative Name: DNS:localhost, IP Address:192.168.0.1, IP Address:127.0.0.1 Signature Algorithm: 1.2.156.10197.1.501 30:45:02:20:7f:27:cf:23:2e:53:15:e7:0c:23:3a:6d:3b:23: f8:6a:8e:6d:cb:ed:6a:af:e5:a3:46:d3:2a:2d:f0:21:1e:d6: 02:21:00:bf:81:4e:74:19:e2:fe:bc:25:86:1b:39:12:8f:b5: f5:15:76:14:29:f1:5f:9b:32:da:13:b1:1c:bb:3a:f4:8f