Skip to content

Instantly share code, notes, and snippets.

@SoulSu
Created December 18, 2018 11:49
Show Gist options
  • Save SoulSu/158a6309e73e4821e606a3875347ac92 to your computer and use it in GitHub Desktop.
Save SoulSu/158a6309e73e4821e606a3875347ac92 to your computer and use it in GitHub Desktop.
使用Golang生成证书 公钥 私钥
package tools
import (
"bytes"
"crypto/rand"
"crypto/rsa"
"crypto/x509"
"crypto/x509/pkix"
"encoding/asn1"
"encoding/pem"
"math/big"
"time"
)
// --------------------------------- 证书相关 ---------------------------------
type RsaKey struct {
bits int
errs []error
cerExpireDay time.Duration
privateKey *rsa.PrivateKey // 公钥
publicKey *rsa.PublicKey // 私钥
certificate *x509.Certificate // 证书
prikBuf *bytes.Buffer
pubkBuf *bytes.Buffer
cerBuf *bytes.Buffer
}
// bits 生成位数
// cerExpireDay 证书过期时间 单位:天
func NewRsaKey(bits int, cerExpireDay int) *RsaKey {
return &RsaKey{
bits: bits,
errs: make([]error, 0),
cerExpireDay: time.Duration(cerExpireDay),
prikBuf: bytes.NewBuffer(nil),
pubkBuf: bytes.NewBuffer(nil),
cerBuf: bytes.NewBuffer(nil),
}
}
func (r *RsaKey) Errors() []error {
return r.errs
}
func (r *RsaKey) addErr(err error) {
if err != nil {
r.errs = append(r.errs, err)
}
}
// todo
func (r *RsaKey) PackToPKCS12() {
//exec.Command()
}
func (r *RsaKey) GenPrivateKey() *RsaKey {
if r.privateKey == nil {
var err error
r.privateKey, err = rsa.GenerateKey(rand.Reader, r.bits)
r.publicKey = &r.privateKey.PublicKey
r.addErr(err)
}
return r
}
// 生成符合PKCS8签名规范的私钥
func (r *RsaKey) MarshalPKCS8PrivateKey() string {
r.GenPrivateKey()
info := struct {
Version int
PrivateKeyAlgorithm []asn1.ObjectIdentifier
PrivateKey []byte
}{}
info.Version = 0
info.PrivateKeyAlgorithm = make([]asn1.ObjectIdentifier, 1)
info.PrivateKeyAlgorithm[0] = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 1}
info.PrivateKey = x509.MarshalPKCS1PrivateKey(r.privateKey)
pkcs8PrivateByte, err := asn1.Marshal(info)
r.addErr(err)
block := &pem.Block{
Type: "RSA PRIVATE KEY",
Bytes: pkcs8PrivateByte,
}
r.addErr(pem.Encode(r.prikBuf, block))
return r.prikBuf.String()
}
// 通过私钥生成公钥
func (r *RsaKey) MarshalPKIXPublicKey() string {
r.GenPrivateKey()
derPkix, err := x509.MarshalPKIXPublicKey(r.publicKey)
r.addErr(err)
block := &pem.Block{
Type: "PUBLIC KEY",
Bytes: derPkix,
}
r.addErr(pem.Encode(r.pubkBuf, block))
return r.pubkBuf.String()
}
// 生成证书
func (r *RsaKey) MarshalCreateCertificate() string {
r.GenPrivateKey()
var (
notBefore time.Time
err error
)
validFrom := ""
validFor := r.cerExpireDay * 24 * time.Hour
if len(validFrom) == 0 {
notBefore = time.Now()
} else {
notBefore, err = time.Parse("Jan 2 15:04:05 2006", validFrom)
if err != nil {
r.addErr(err)
return ""
}
}
notAfter := notBefore.Add(validFor)
serialNumberLimit := new(big.Int).Lsh(big.NewInt(1), 128)
serialNumber, err := rand.Int(rand.Reader, serialNumberLimit)
if err != nil {
r.addErr(err)
return ""
}
template := x509.Certificate{
SerialNumber: serialNumber,
Subject: pkix.Name{
Organization: []string{"NewSkyPay"},
CommonName: "NewSkyPay",
Country: []string{"CN"},
},
NotBefore: notBefore,
NotAfter: notAfter,
KeyUsage: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature,
ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth},
BasicConstraintsValid: true,
}
derBytes, err := x509.CreateCertificate(rand.Reader, &template, &template, r.publicKey, r.privateKey)
if err != nil {
r.addErr(err)
return ""
}
block := &pem.Block{Type: "CERTIFICATE", Bytes: derBytes}
r.addErr(pem.Encode(r.cerBuf, block))
return r.cerBuf.String()
}
// --------------------------------- 证书相关 ---------------------------------
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment