encryption

package
v1.2.6 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 11, 2025 License: MIT Imports: 6 Imported by: 0

README

Encryption Package

Home  /  Encryption Package

 

This package provides comprehensive message encryption capabilities for the go-rabbitmq library, including industry-standard AES-GCM encryption and a pluggable interface for custom encryption implementations.

 

Features

  • AES-256-GCM Encryption: Industry-standard authenticated encryption
  • Automatic Nonce Generation: Secure random nonce for each encryption operation
  • Authenticated Encryption: Built-in integrity verification prevents tampering
  • Zero Configuration: Secure defaults with minimal setup required
  • Performance Optimized: Efficient implementations for high-throughput scenarios
  • Pluggable Interface: Easy to implement custom encryption algorithms

🔝 back to top

 

Installation

go get github.com/cloudresty/go-rabbitmq/encryption

🔝 back to top

 

Basic Usage

AES-GCM Encryption
import (
    "crypto/rand"
    "github.com/cloudresty/go-rabbitmq"
    "github.com/cloudresty/go-rabbitmq/encryption"
)

func main() {
    // Generate a secure 256-bit encryption key
    key := make([]byte, 32)
    if _, err := rand.Read(key); err != nil {
        log.Fatal("Failed to generate encryption key:", err)
    }

    // Create AES-GCM encryptor
    encryptor, err := encryption.NewAESGCM(key)
    if err != nil {
        log.Fatal("Failed to create encryptor:", err)
    }

    // Create publisher with encryption
    publisher, err := rabbitmq.NewPublisher(
        rabbitmq.WithHosts("localhost:5672"),
        rabbitmq.WithCredentials("guest", "guest"),
        rabbitmq.WithEncryption(encryptor),
        rabbitmq.WithConnectionName("secure-publisher"),
    )
    if err != nil {
        log.Fatal("Failed to create publisher:", err)
    }
    defer publisher.Close()

    // Messages are automatically encrypted before publishing
    message := rabbitmq.NewMessage([]byte("sensitive data"))
    err = publisher.Publish(ctx, "secure.exchange", "routing.key", message)
    if err != nil {
        log.Fatal("Failed to publish encrypted message:", err)
    }
}

🔝 back to top

 

Consumer with Automatic Decryption
import (
    "github.com/cloudresty/go-rabbitmq"
    "github.com/cloudresty/go-rabbitmq/encryption"
)

func main() {
    // Use the same encryption key as the publisher
    encryptor, err := encryption.NewAESGCM(key)
    if err != nil {
        log.Fatal("Failed to create encryptor:", err)
    }

    // Create consumer with automatic decryption
    consumer, err := rabbitmq.NewConsumer(
        rabbitmq.WithHosts("localhost:5672"),
        rabbitmq.WithCredentials("guest", "guest"),
        rabbitmq.WithConsumerEncryption(encryptor),
        rabbitmq.WithConnectionName("secure-consumer"),
    )
    if err != nil {
        log.Fatal("Failed to create consumer:", err)
    }
    defer consumer.Close()

    // Consume messages (automatically decrypted)
    err = consumer.Consume(ctx, "secure.queue", func(delivery *rabbitmq.Delivery) error {
        // Message body is automatically decrypted before reaching this handler
        log.Printf("Received decrypted message: %s", string(delivery.Body))

        // Check encryption header
        if alg, ok := delivery.Headers["x-encryption"]; ok {
            log.Printf("Message was encrypted with: %v", alg)
        }

        return nil
    })
}

🔝 back to top

 

Advanced Usage

Custom Encryption Implementation

You can implement your own encryption algorithm by satisfying the MessageEncryptor interface:

type CustomEncryptor struct {
    // Your custom encryption state
}

func (c *CustomEncryptor) Encrypt(data []byte) ([]byte, error) {
    // Your encryption logic
    return encryptedData, nil
}

func (c *CustomEncryptor) Decrypt(data []byte) ([]byte, error) {
    // Your decryption logic
    return decryptedData, nil
}

func (c *CustomEncryptor) Algorithm() string {
    return "custom-algorithm-v1"
}

// Use with publisher/consumer
publisher, err := rabbitmq.NewPublisher(
    rabbitmq.WithEncryption(&CustomEncryptor{}),
)

🔝 back to top

 

Key Management Best Practices
import (
    "crypto/rand"
    "encoding/base64"
    "os"
)

func generateSecureKey() []byte {
    key := make([]byte, 32) // 256-bit key
    if _, err := rand.Read(key); err != nil {
        panic("Failed to generate secure key")
    }
    return key
}

func keyFromEnvironment() ([]byte, error) {
    keyStr := os.Getenv("ENCRYPTION_KEY")
    if keyStr == "" {
        return nil, fmt.Errorf("ENCRYPTION_KEY environment variable not set")
    }

    return base64.StdEncoding.DecodeString(keyStr)
}

func main() {
    // Option 1: Generate new key (for development)
    key := generateSecureKey()

    // Option 2: Load from environment (for production)
    // key, err := keyFromEnvironment()

    encryptor, err := encryption.NewAESGCM(key)
    // ... rest of setup
}

🔝 back to top

 

Combined with Compression

Encryption works seamlessly with other features like compression:

import (
    "github.com/cloudresty/go-rabbitmq"
    "github.com/cloudresty/go-rabbitmq/encryption"
    "github.com/cloudresty/go-rabbitmq/compression"
)

func main() {
    encryptor, _ := encryption.NewAESGCM(key)
    compressor := compression.NewGzip()

    // Publisher with both encryption and compression
    publisher, err := rabbitmq.NewPublisher(
        rabbitmq.WithEncryption(encryptor),    // Encrypt first
        rabbitmq.WithCompression(compressor),  // Then compress
        rabbitmq.WithCompressionThreshold(100), // Compress messages >100 bytes
    )

    // Consumer with automatic decompression and decryption
    consumer, err := rabbitmq.NewConsumer(
        rabbitmq.WithConsumerCompression(compressor), // Decompress first
        rabbitmq.WithConsumerEncryption(encryptor),   // Then decrypt
    )
}

🔝 back to top

 

Security Considerations

Key Management
  • Use 256-bit keys: Always use 32-byte keys for AES-256-GCM
  • Secure key generation: Use crypto/rand for key generation
  • Key rotation: Implement regular key rotation policies
  • Environment variables: Store keys in environment variables, not in code
  • Key derivation: Consider using key derivation functions (KDF) for password-based keys

🔝 back to top

 

Best Practices
// ✅ Good: Secure key generation
key := make([]byte, 32)
if _, err := rand.Read(key); err != nil {
    log.Fatal("Failed to generate key:", err)
}

// ✅ Good: Load key from environment
keyStr := os.Getenv("ENCRYPTION_KEY")
key, err := base64.StdEncoding.DecodeString(keyStr)

// ❌ Bad: Hardcoded key
key := []byte("this-is-not-secure-32-byte-key!!") // Don't do this!

// ❌ Bad: Weak key generation
key := make([]byte, 32)
for i := range key {
    key[i] = byte(i) // Predictable pattern
}

🔝 back to top

 

Compliance and Standards
  • FIPS 140-2: AES-GCM is FIPS approved for sensitive data
  • Common Criteria: EAL4+ certified implementations available
  • GDPR: Encryption satisfies "appropriate technical measures" requirement
  • HIPAA: Suitable for PHI encryption requirements
  • PCI DSS: Approved for payment card data protection

🔝 back to top

 

Performance Considerations

Benchmarks

On typical hardware (Intel i7, 2.6GHz):

  • Encryption: ~500 MB/s for 1KB messages
  • Decryption: ~520 MB/s for 1KB messages
  • Memory overhead: ~28 bytes per message (nonce + auth tag)

🔝 back to top

 

Optimization Tips
// For high-throughput scenarios
publisher, err := rabbitmq.NewPublisher(
    rabbitmq.WithEncryption(encryptor),
    rabbitmq.WithCompression(compressor),
    rabbitmq.WithCompressionThreshold(512), // Only compress larger messages
    rabbitmq.WithConnectionPoolSize(10), // Connection pooling
)

🔝 back to top

 

Error Handling

encryptor, err := encryption.NewAESGCM(key)
if err != nil {
    // Handle key validation errors
    log.Printf("Invalid encryption key: %v", err)
    return
}

err = publisher.Publish(ctx, exchange, routingKey, message)
if err != nil {
    // Encryption errors are wrapped in publish errors
    if strings.Contains(err.Error(), "encryption failed") {
        log.Printf("Message encryption failed: %v", err)
    }
}

🔝 back to top

 

Dependencies

  • Go: 1.19 or later
  • crypto/aes: Standard library AES implementation
  • crypto/cipher: Standard library GCM mode
  • crypto/rand: Secure random number generation

🔝 back to top

 

Troubleshooting

Common Issues

Invalid key length error:

AES-GCM requires 32-byte key, got 16 bytes

Solution: Use exactly 32 bytes for AES-256-GCM.

 

Decryption failed error:

decryption failed: cipher: message authentication failed

Solution: Ensure publisher and consumer use the same encryption key.

 

Ciphertext too short error:

ciphertext too short: expected at least 12 bytes, got 8

Solution: The message may be corrupted or not properly encrypted.

 

Debug Mode
// Enable debug logging to troubleshoot encryption issues
publisher, err := rabbitmq.NewPublisher(
    rabbitmq.WithEncryption(encryptor),
    rabbitmq.WithLogger(logger), // Add structured logging
)

🔝 back to top

 

Examples

Complete examples are available in the examples/encryption-features directory.

 


 

Security Notice: This implementation is suitable for production use but should be reviewed by security professionals for high-security applications. Consider additional measures like key rotation, secure key storage, and audit logging for enterprise deployments.

🔝 back to top

 


 

An open source project brought to you by the Cloudresty team.

Website  |  LinkedIn  |  BlueSky  |  GitHub  |  Docker Hub

 

Documentation

Overview

Package encryption provides message encryption/decryption capabilities for the go-rabbitmq library.

This package implements industry-standard encryption algorithms for securing message data in transit and at rest. It supports AES-GCM encryption and provides a pluggable interface for custom encryption implementations.

Features:

  • AES-256-GCM encryption with authenticated encryption
  • Automatic nonce generation and validation
  • Pluggable encryption interface for custom algorithms
  • Zero-configuration setup with secure defaults
  • Performance-optimized implementations

Example usage:

// Create AES-GCM encryptor
key := make([]byte, 32) // 256-bit key
rand.Read(key)
encryptor := encryption.NewAESGCM(key)

// Use with publisher
publisher, err := rabbitmq.NewPublisher(
	rabbitmq.WithEncryption(encryptor),
)

// Messages are automatically encrypted before publishing
err = publisher.Publish(ctx, "secure.exchange", "key", message)

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func NewNoEncryption

func NewNoEncryption() rabbitmq.MessageEncryptor

NewNoEncryption creates a no-op encryptor for testing and development. This encryptor passes data through unchanged.

Types

type AESGCM

type AESGCM struct {
	// contains filtered or unexported fields
}

AESGCM implements the MessageEncryptor interface using AES-GCM encryption. AES-GCM provides both confidentiality and authenticity, making it ideal for message encryption in distributed systems.

func NewAESGCM

func NewAESGCM(key []byte) (*AESGCM, error)

NewAESGCM creates a new AES-GCM encryptor with the provided key. The key must be exactly 32 bytes (256 bits) for AES-256-GCM.

func (*AESGCM) Algorithm

func (a *AESGCM) Algorithm() string

Algorithm returns the encryption algorithm identifier.

func (*AESGCM) Decrypt

func (a *AESGCM) Decrypt(data []byte) ([]byte, error)

Decrypt decrypts the provided data using AES-GCM. Expects the nonce to be prepended to the ciphertext.

func (*AESGCM) Encrypt

func (a *AESGCM) Encrypt(data []byte) ([]byte, error)

Encrypt encrypts the provided data using AES-GCM. Returns the encrypted data with the nonce prepended.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL