package crypto import ( "crypto/ecdsa" "crypto/elliptic" "crypto/rand" "crypto/tls" "crypto/x509" "crypto/x509/pkix" "encoding/pem" "math/big" "net" "os" "time" ) // GenerateSelfSignedCert 生成自签名证书 func GenerateSelfSignedCert(certFile, keyFile string) error { priv, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader) if err != nil { return err } serialNumber, err := rand.Int(rand.Reader, new(big.Int).Lsh(big.NewInt(1), 128)) if err != nil { return err } template := x509.Certificate{ SerialNumber: serialNumber, Subject: pkix.Name{ Organization: []string{"GoTunnel"}, CommonName: "GoTunnel Server", }, NotBefore: time.Now(), NotAfter: time.Now().AddDate(10, 0, 0), // 10年有效期 KeyUsage: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature, ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth}, BasicConstraintsValid: true, IPAddresses: []net.IP{net.ParseIP("127.0.0.1")}, DNSNames: []string{"localhost"}, } certDER, err := x509.CreateCertificate(rand.Reader, &template, &template, &priv.PublicKey, priv) if err != nil { return err } // 写入证书文件 certOut, err := os.Create(certFile) if err != nil { return err } defer certOut.Close() pem.Encode(certOut, &pem.Block{Type: "CERTIFICATE", Bytes: certDER}) // 写入私钥文件 keyOut, err := os.Create(keyFile) if err != nil { return err } defer keyOut.Close() privBytes, err := x509.MarshalECPrivateKey(priv) if err != nil { return err } pem.Encode(keyOut, &pem.Block{Type: "EC PRIVATE KEY", Bytes: privBytes}) return nil }