mirror of
				https://github.com/oarkflow/mq.git
				synced 2025-10-31 07:36:27 +08:00 
			
		
		
		
	
		
			
				
	
	
		
			201 lines
		
	
	
		
			5.5 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			201 lines
		
	
	
		
			5.5 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| package main
 | |
| 
 | |
| import (
 | |
| 	"crypto/rand"
 | |
| 	"crypto/rsa"
 | |
| 	"crypto/x509"
 | |
| 	"crypto/x509/pkix"
 | |
| 	"encoding/pem"
 | |
| 	"log"
 | |
| 	"math/big"
 | |
| 	"os"
 | |
| 	"time"
 | |
| )
 | |
| 
 | |
| func main() {
 | |
| 	// 1. Generate the CA private key
 | |
| 	caPrivateKey, err := generatePrivateKey(2048)
 | |
| 	if err != nil {
 | |
| 		log.Fatalf("Failed to generate CA private key: %v", err)
 | |
| 	}
 | |
| 	err = savePrivateKey("ca.key", caPrivateKey)
 | |
| 	if err != nil {
 | |
| 		log.Fatalf("Failed to save CA private key: %v", err)
 | |
| 	}
 | |
| 
 | |
| 	// 2. Generate the CA certificate
 | |
| 	caCertBytes, caCert, err := generateCACertificate(caPrivateKey)
 | |
| 	if err != nil {
 | |
| 		log.Fatalf("Failed to generate CA certificate: %v", err)
 | |
| 	}
 | |
| 	err = saveCertificate("ca.crt", caCertBytes)
 | |
| 	if err != nil {
 | |
| 		log.Fatalf("Failed to save CA certificate: %v", err)
 | |
| 	}
 | |
| 
 | |
| 	log.Println("CA Certificate and key generated")
 | |
| 
 | |
| 	// 3. Generate the server certificate
 | |
| 	serverCertBytes, serverPrivateKey, err := generateSignedCertificate(caCert, caPrivateKey, "server", true)
 | |
| 	if err != nil {
 | |
| 		log.Fatalf("Failed to generate server certificate: %v", err)
 | |
| 	}
 | |
| 	err = saveCertificate("server.crt", serverCertBytes)
 | |
| 	if err != nil {
 | |
| 		log.Fatalf("Failed to save server certificate: %v", err)
 | |
| 	}
 | |
| 	err = savePrivateKey("server.key", serverPrivateKey)
 | |
| 	if err != nil {
 | |
| 		log.Fatalf("Failed to save server private key: %v", err)
 | |
| 	}
 | |
| 
 | |
| 	log.Println("Server certificate and key generated")
 | |
| 
 | |
| 	// 4. Generate the publisher certificate
 | |
| 	publisherCertBytes, publisherPrivateKey, err := generateSignedCertificate(caCert, caPrivateKey, "publisher", false)
 | |
| 	if err != nil {
 | |
| 		log.Fatalf("Failed to generate publisher certificate: %v", err)
 | |
| 	}
 | |
| 	err = saveCertificate("publisher.crt", publisherCertBytes)
 | |
| 	if err != nil {
 | |
| 		log.Fatalf("Failed to save publisher certificate: %v", err)
 | |
| 	}
 | |
| 	err = savePrivateKey("publisher.key", publisherPrivateKey)
 | |
| 	if err != nil {
 | |
| 		log.Fatalf("Failed to save publisher private key: %v", err)
 | |
| 	}
 | |
| 
 | |
| 	log.Println("Publisher certificate and key generated")
 | |
| 
 | |
| 	// 5. Generate the consumer certificate
 | |
| 	consumerCertBytes, consumerPrivateKey, err := generateSignedCertificate(caCert, caPrivateKey, "consumer", false)
 | |
| 	if err != nil {
 | |
| 		log.Fatalf("Failed to generate consumer certificate: %v", err)
 | |
| 	}
 | |
| 	err = saveCertificate("consumer.crt", consumerCertBytes)
 | |
| 	if err != nil {
 | |
| 		log.Fatalf("Failed to save consumer certificate: %v", err)
 | |
| 	}
 | |
| 	err = savePrivateKey("consumer.key", consumerPrivateKey)
 | |
| 	if err != nil {
 | |
| 		log.Fatalf("Failed to save consumer private key: %v", err)
 | |
| 	}
 | |
| 
 | |
| 	log.Println("Consumer certificate and key generated")
 | |
| }
 | |
| 
 | |
| // Generate a private key
 | |
| func generatePrivateKey(bits int) (*rsa.PrivateKey, error) {
 | |
| 	privateKey, err := rsa.GenerateKey(rand.Reader, bits)
 | |
| 	if err != nil {
 | |
| 		return nil, err
 | |
| 	}
 | |
| 	return privateKey, nil
 | |
| }
 | |
| 
 | |
| // Save private key to file
 | |
| func savePrivateKey(filename string, privateKey *rsa.PrivateKey) error {
 | |
| 	keyOut, err := os.Create(filename)
 | |
| 	if err != nil {
 | |
| 		return err
 | |
| 	}
 | |
| 	defer keyOut.Close()
 | |
| 
 | |
| 	privateKeyPEM := pem.Block{
 | |
| 		Type:  "RSA PRIVATE KEY",
 | |
| 		Bytes: x509.MarshalPKCS1PrivateKey(privateKey),
 | |
| 	}
 | |
| 
 | |
| 	return pem.Encode(keyOut, &privateKeyPEM)
 | |
| }
 | |
| 
 | |
| // Generate a self-signed certificate for the CA
 | |
| func generateCACertificate(privateKey *rsa.PrivateKey) ([]byte, *x509.Certificate, error) {
 | |
| 	serialNumber, err := rand.Int(rand.Reader, new(big.Int).Lsh(big.NewInt(1), 128))
 | |
| 	if err != nil {
 | |
| 		return nil, nil, err
 | |
| 	}
 | |
| 
 | |
| 	caTemplate := x509.Certificate{
 | |
| 		SerialNumber: serialNumber,
 | |
| 		Subject: pkix.Name{
 | |
| 			Organization:  []string{"My CA"},
 | |
| 			Country:       []string{"US"},
 | |
| 			Province:      []string{""},
 | |
| 			Locality:      []string{"My City"},
 | |
| 			StreetAddress: []string{"My Street"},
 | |
| 			PostalCode:    []string{"00000"},
 | |
| 			CommonName:    "My CA",
 | |
| 		},
 | |
| 		NotBefore:             time.Now(),
 | |
| 		NotAfter:              time.Now().Add(365 * 24 * time.Hour), // 1 year validity
 | |
| 		KeyUsage:              x509.KeyUsageCertSign | x509.KeyUsageDigitalSignature,
 | |
| 		IsCA:                  true,
 | |
| 		BasicConstraintsValid: true,
 | |
| 		MaxPathLen:            0,
 | |
| 	}
 | |
| 
 | |
| 	caCertBytes, err := x509.CreateCertificate(rand.Reader, &caTemplate, &caTemplate, &privateKey.PublicKey, privateKey)
 | |
| 	if err != nil {
 | |
| 		return nil, nil, err
 | |
| 	}
 | |
| 
 | |
| 	caCert, err := x509.ParseCertificate(caCertBytes)
 | |
| 	if err != nil {
 | |
| 		return nil, nil, err
 | |
| 	}
 | |
| 
 | |
| 	return caCertBytes, caCert, nil
 | |
| }
 | |
| 
 | |
| // Save the certificate to a file
 | |
| func saveCertificate(filename string, certBytes []byte) error {
 | |
| 	certOut, err := os.Create(filename)
 | |
| 	if err != nil {
 | |
| 		return err
 | |
| 	}
 | |
| 	defer certOut.Close()
 | |
| 
 | |
| 	certPEM := pem.Block{
 | |
| 		Type:  "CERTIFICATE",
 | |
| 		Bytes: certBytes,
 | |
| 	}
 | |
| 	return pem.Encode(certOut, &certPEM)
 | |
| }
 | |
| 
 | |
| // Generate a signed certificate using the CA
 | |
| func generateSignedCertificate(caCert *x509.Certificate, caPrivateKey *rsa.PrivateKey, commonName string, isServer bool) ([]byte, *rsa.PrivateKey, error) {
 | |
| 	privateKey, err := generatePrivateKey(2048)
 | |
| 	if err != nil {
 | |
| 		return nil, nil, err
 | |
| 	}
 | |
| 
 | |
| 	serialNumber, err := rand.Int(rand.Reader, new(big.Int).Lsh(big.NewInt(1), 128))
 | |
| 	if err != nil {
 | |
| 		return nil, nil, err
 | |
| 	}
 | |
| 
 | |
| 	certTemplate := x509.Certificate{
 | |
| 		SerialNumber: serialNumber,
 | |
| 		Subject: pkix.Name{
 | |
| 			CommonName: commonName,
 | |
| 		},
 | |
| 		NotBefore:   time.Now(),
 | |
| 		NotAfter:    time.Now().Add(365 * 24 * time.Hour), // 1 year
 | |
| 		KeyUsage:    x509.KeyUsageDigitalSignature,
 | |
| 		ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth, x509.ExtKeyUsageServerAuth},
 | |
| 	}
 | |
| 
 | |
| 	if isServer {
 | |
| 		certTemplate.KeyUsage |= x509.KeyUsageKeyEncipherment
 | |
| 		certTemplate.ExtKeyUsage = []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth}
 | |
| 	}
 | |
| 
 | |
| 	certBytes, err := x509.CreateCertificate(rand.Reader, &certTemplate, caCert, &privateKey.PublicKey, caPrivateKey)
 | |
| 	if err != nil {
 | |
| 		return nil, nil, err
 | |
| 	}
 | |
| 
 | |
| 	return certBytes, privateKey, nil
 | |
| }
 | 
