主代码: package rsa import ( "crypto/rand" "crypto/rsa" "crypto/x509" "crypto/x509/pkix" "encoding/pem" "io/ioutil" "math/big" rd "math/rand" "os" "time" ) func init() { rd.Seed(time.Now().UnixNano()) } type CertInformation struct { Country []string Organization []string OrganizationalUnit []string EmailAddress []string Province []string Locality []string CommonName string CrtName, KeyName string IsCA bool Names []pkix.AttributeTypeAndValue } func CreateCRT(RootCa *x509.Certificate, RootKey *rsa.PrivateKey, info CertInformation) error { Crt := newCertificate(info) Key, err := rsa.GenerateKey(rand.Reader, 2048) if err != nil { return err } var buf []byte if RootCa == nil || RootKey == nil { //创建自签名证书 buf, err = x509.CreateCertificate(rand.Reader, Crt, Crt, &Key.PublicKey, Key) } else { //使用根证书签名 buf, err = x509.CreateCertificate(rand.Reader, Crt, RootCa, &Key.PublicKey, RootKey) } if err != nil { return err } err = write(info.CrtName, "CERTIFICATE", buf) if err != nil { return err } buf = x509.MarshalPKCS1PrivateKey(Key) return write(info.KeyName, "PRIVATE KEY", buf) } //编码写入文件 func write(filename, Type string, p []byte) error { File, err := os.Create(filename) defer File.Close() if err != nil { return err } var b *pem.Block = &pem.Block{Bytes: p, Type: Type} return pem.Encode(File, b) } func Parse(crtPath, keyPath string) (rootcertificate *x509.Certificate, rootPrivateKey *rsa.PrivateKey, err error) { rootcertificate, err = ParseCrt(crtPath) if err != nil { return } rootPrivateKey, err = ParseKey(keyPath) return } func ParseCrt(path string) (*x509.Certificate, error) { buf, err := ioutil.ReadFile(path) if err != nil { return nil, err } p := &pem.Block{} p, buf = pem.Decode(buf) return x509.ParseCertificate(p.Bytes) } func ParseKey(path string) (*rsa.PrivateKey, error) { buf, err := ioutil.ReadFile(path) if err != nil { return nil, err } p, buf := pem.Decode(buf) return x509.ParsePKCS1PrivateKey(p.Bytes) } func newCertificate(info CertInformation) *x509.Certificate { return &x509.Certificate{ SerialNumber: big.NewInt(rd.Int63()), Subject: pkix.Name{ Country: info.Country, Organization: info.Organization, OrganizationalUnit: info.OrganizationalUnit, Province: info.Province, CommonName: info.CommonName, Locality: info.Locality, ExtraNames: info.Names, }, NotBefore: time.Now(),//证书的开始时间 NotAfter: time.Now().AddDate(20, 0, 0),//证书的结束时间 BasicConstraintsValid: true, //基本的有效性约束 IsCA: info.IsCA, //是否是根证书 ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth, x509.ExtKeyUsageServerAuth}, //证书用途 KeyUsage: x509.KeyUsageDigitalSignature | x509.KeyUsageCertSign, EmailAddresses: info.EmailAddress, } }
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
- 93
- 94
- 95
- 96
- 97
- 98
- 99
- 100
- 101
- 102
- 103
- 104
- 105
- 106
- 107
- 108
- 109
- 110
- 111
- 112
- 113
- 114
- 115
- 116
- 117
- 118
- 119
- 120
- 121
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
- 93
- 94
- 95
- 96
- 97
- 98
- 99
- 100
- 101
- 102
- 103
- 104
- 105
- 106
- 107
- 108
- 109
- 110
- 111
- 112
- 113
- 114
- 115
- 116
- 117
- 118
- 119
- 120
- 121
测试代码: package rsa import ( "crypto/x509/pkix" "encoding/asn1" "os" "testing" ) func Test_crt(t *testing.T) { baseinfo := CertInformation{Country: []string{"CN"}, Organization: []string{"WS"}, IsCA: true, OrganizationalUnit: []string{"work-stacks"}, EmailAddress: []string{"czxichen@163.com"}, Locality: []string{"SuZhou"}, Province: []string{"JiangSu"}, CommonName: "Work-Stacks", CrtName: "test_root.crt", KeyName: "test_root.key"} err := CreateCRT(nil, nil, baseinfo) if err != nil { t.Log("Create crt error,Error info:", err) return } crtinfo := baseinfo crtinfo.IsCA = false crtinfo.CrtName = "test_server.crt" crtinfo.KeyName = "test_server.key" crtinfo.Names = []pkix.AttributeTypeAndValue{{asn1.ObjectIdentifier{2, 1, 3}, "MAC_ADDR"}} //添加扩展字段用来做自定义使用 crt, pri, err := Parse(baseinfo.CrtName, baseinfo.KeyName) if err != nil { t.Log("Parse crt error,Error info:", err) return } err = CreateCRT(crt, pri, crtinfo) if err != nil { t.Log("Create crt error,Error info:", err) } os.Remove(baseinfo.CrtName) os.Remove(baseinfo.KeyName) os.Remove(crtinfo.CrtName) os.Remove(crtinfo.KeyName) }
http://blog.csdn.net/fyxichen/article/details/53010255