encx

package module
v0.5.1 Latest Latest
Warning

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

Go to latest
Published: Oct 10, 2025 License: MIT Imports: 18 Imported by: 0

README

ENCX - Enterprise Cryptography for Go

Context7 Users: See Quick Integration Guide for structured examples and patterns

A production-ready Go library for field-level encryption, hashing, and key management. ENCX provides struct-based cryptographic operations with support for key rotation, multiple KMS backends, and comprehensive testing utilities.

🚀 Context7 Quick Start

// Install: go get github.com/hengadev/encx

// Define struct with encryption tags (no companion fields needed)
type User struct {
    Email    string `encx:"encrypt,hash_basic"` // Encrypt + searchable
    Password string `encx:"hash_secure"`        // Secure password hash
}

// Generate code using one of 3 options:
// 1. go run ./cmd/encx-gen generate .
// 2. Build first: go build -o bin/encx-gen ./cmd/encx-gen && ./bin/encx-gen generate .
// 3. Add: //go:generate go run ../../cmd/encx-gen generate .  (path must be relative)

// Use generated functions for type-safe encryption
crypto, _ := encx.NewTestCrypto(nil)
user := &User{Email: "user@example.com", Password: "secret123"}

// Process returns separate struct with encrypted/hashed fields
// Note: Function name follows pattern Process<YourStructName>Encx
// For a User struct, it generates ProcessUserEncx
userEncx, err := ProcessUserEncx(ctx, crypto, user)

// userEncx.EmailEncrypted contains encrypted email
// userEncx.EmailHash contains searchable hash
// userEncx.PasswordHashSecure contains secure hash

// Decrypt when needed
// Note: Function name follows pattern Decrypt<YourStructName>Encx
decryptedUser, err := DecryptUserEncx(ctx, crypto, userEncx)

See all patterns and use cases

Features

  • Field-level encryption with AES-GCM
  • Secure hashing with Argon2id and basic SHA-256
  • Combined operations - encrypt AND hash the same field
  • Automatic key management with DEK/KEK architecture
  • Key rotation support with version tracking
  • Multiple KMS backends (AWS KMS, HashiCorp Vault, etc.)
  • Comprehensive testing utilities and mocks
  • Compile-time validation for struct tags

Quick Start

Installation
go get github.com/hengadev/encx
Basic Usage
package main

import (
    "context"
    "fmt"
    "log"

    "github.com/hengadev/encx"
)

// Define your struct with encx tags (no companion fields needed)
type User struct {
    Name     string `encx:"encrypt"`
    Email    string `encx:"hash_basic"`
    Password string `encx:"hash_secure"`
}

// Run code generation using one of 3 options:
// 1. go run ./cmd/encx-gen generate .
// 2. Build first: go build -o bin/encx-gen ./cmd/encx-gen && ./bin/encx-gen generate .
// 3. Add: //go:generate go run ../../cmd/encx-gen generate .  (path must be relative)

func main() {
    ctx := context.Background()
    crypto, _ := encx.NewTestCrypto(nil)

    // Create user with sensitive data
    user := &User{
        Name:     "John Doe",
        Email:    "john@example.com",
        Password: "secret123",
    }

    // Process returns encrypted struct (generated function)
    // Note: For your struct, replace "User" with your actual struct name
    // Example: ProcessCustomerEncx, ProcessOrderEncx, etc.
    userEncx, err := ProcessUserEncx(ctx, crypto, user)
    if err != nil {
        log.Fatal(err)
    }

    // Store encrypted data in database
    fmt.Printf("NameEncrypted: %d bytes\n", len(userEncx.NameEncrypted))
    fmt.Printf("EmailHash: %s\n", userEncx.EmailHash[:16]+"...")
    fmt.Printf("PasswordHashSecure: %s...\n", userEncx.PasswordHashSecure[:20]+"...")

    // Decrypt when needed (generated function)
    decryptedUser, err := DecryptUserEncx(ctx, crypto, userEncx)
    if err != nil {
        log.Fatal(err)
    }

    fmt.Printf("Decrypted Name: %s\n", decryptedUser.Name)
}

Struct Tags Reference

Single Operation Tags
  • encx:"encrypt" - Encrypts field value
  • encx:"hash_basic" - Creates SHA-256 hash for searchable indexing
  • encx:"hash_secure" - Creates Argon2id hash with pepper (for passwords)
Combined Operation Tags
  • encx:"encrypt,hash_basic" - Both encrypts AND hashes the field (searchable encryption)
  • encx:"hash_secure,encrypt" - Secure hash for auth + encryption for recovery
How It Works

encx-gen discovers structs automatically by parsing Go source files. No special directives required.

Code Generation Methods:

Code Generation: 3 Working Options

# Build the tool once
go build -o bin/encx-gen ./cmd/encx-gen

# Generate code for current directory and all subdirectories recursively
./bin/encx-gen generate .

# Generate code for specific packages
./bin/encx-gen generate ./path/to/package
Option 2: Go Run (RELIABLE)
# No building needed - runs directly from source
go run ./cmd/encx-gen generate ./path/to/package

# Generate code for current directory and all subdirectories recursively
go run ./cmd/encx-gen generate .

# Works from any directory with correct relative path
go run ../../cmd/encx-gen generate .
Option 3: Go Generate with Go Run (ADVANCED)

Add this to your Go source file (path must be relative to your file):

//go:generate go run ../../cmd/encx-gen generate .

Then run: go generate ./...

Note: When using encx-gen generate ., the tool automatically discovers all Go packages in subdirectories recursively, making it ideal for processing entire projects from the root directory.

⚠️ Note: Option 3 requires the correct relative path to cmd/encx-gen. Options 1 & 2 work consistently in all environments.

When you define a struct with encx tags:

// Your source struct - clean and simple
type User struct {
    Email string `encx:"encrypt,hash_basic"`
}

// encx-gen automatically generates a UserEncx struct
type UserEncx struct {
    EmailEncrypted []byte   // Encrypted email data
    EmailHash      string   // Searchable hash
    DEKEncrypted   []byte   // Encrypted data encryption key
    KeyVersion     int      // Key version for rotation
    Metadata       string   // Serialization metadata
}

// And generates these functions:
// - ProcessUserEncx(ctx, crypto, user) (*UserEncx, error)
// - DecryptUserEncx(ctx, crypto, userEncx) (*User, error)
//
// Note: Function names follow the pattern Process<StructName>Encx
// Replace "User" with your actual struct name

Advanced Examples

Combined Tags for Email (Searchable Encryption)

Perfect for user lookup + privacy using code generation:

// Source struct - clean definition
type User struct {
    Email string `encx:"encrypt,hash_basic"`
}

// Run: go run ./cmd/encx-gen generate .

// Usage
user := &User{Email: "user@example.com"}
userEncx, err := ProcessUserEncx(ctx, crypto, user)

// Generated UserEncx has:
// - EmailEncrypted []byte  // For secure storage
// - EmailHash      string  // For fast user lookups

// Database search example
db.Where("email_hash = ?", userEncx.EmailHash).First(&foundUser)

// Decrypt when needed
decrypted, _ := DecryptUserEncx(ctx, crypto, foundUser)
fmt.Println(decrypted.Email) // "user@example.com"
Password with Recovery

Secure authentication + recovery capability:

type User struct {
    Password string `encx:"hash_secure,encrypt"`
}

// Run: go run ./cmd/encx-gen generate .

// Example: Registration
// (Replace "User" with your actual struct name)
user := &User{Password: "secret123"}
userEncx, _ := ProcessUserEncx(ctx, crypto, user)

// Generated UserEncx has:
// - PasswordHashSecure string // For authentication (Argon2id)
// - PasswordEncrypted  []byte // For recovery scenarios

// Login verification
isValid := crypto.CompareSecureHashAndValue(ctx, inputPassword, userEncx.PasswordHashSecure)

// Password recovery (admin function)
recovered, _ := DecryptUserEncx(ctx, crypto, userEncx)
fmt.Println(recovered.Password) // Original password temporarily available
Embedded Structs

Code generation handles embedded structs automatically:

//go:generate go run ../../cmd/encx-gen generate .

type Address struct {
    Street string `encx:"encrypt"`
    City   string `encx:"hash_basic"`
}

type User struct {
    Name    string  `encx:"encrypt"`
    Address Address // Embedded struct, automatically processed
}

// Example: Usage
// (Replace "User" with your actual struct name)
user := &User{
    Name: "John Doe",
    Address: Address{
        Street: "123 Main St",
        City:   "Springfield",
    },
}

userEncx, _ := ProcessUserEncx(ctx, crypto, user)
// Generated UserEncx includes all encrypted/hashed fields from embedded struct

Configuration

Production Setup
// With AWS KMS
pepper := []byte("your-32-byte-pepper-here!!!!")
crypto, err := encx.NewCrypto(ctx,
    encx.WithKMSService(awsKMS),
    encx.WithKEKAlias("alias/myapp-kek"),
    encx.WithPepper(pepper),
)

// With HashiCorp Vault
pepper := []byte("your-32-byte-pepper-here!!!!")
crypto, err := encx.NewCrypto(ctx,
    encx.WithKMSService(vaultKMS),
    encx.WithKEKAlias("transit/keys/myapp-kek"),
    encx.WithPepper(pepper),
)
Testing Setup
// For unit tests with code generation
func TestUserEncryption(t *testing.T) {
    crypto, _ := encx.NewTestCrypto(t)

    user := &User{Name: "Test User"}
    userEncx, err := ProcessUserEncx(ctx, crypto, user)

    assert.NoError(t, err)
    assert.NotEmpty(t, userEncx.NameEncrypted)
}

// For integration tests
func TestUserEncryptionIntegration(t *testing.T) {
    crypto, _ := encx.NewTestCrypto(t, &encx.TestCryptoOptions{
        Pepper: []byte("test-pepper-exactly-32-bytes!!"),
    })

    // Test full encrypt/decrypt cycle
    user := &User{Name: "Integration Test"}
    userEncx, err := ProcessUserEncx(ctx, crypto, user)
    assert.NoError(t, err)

    decrypted, err := DecryptUserEncx(ctx, crypto, userEncx)
    assert.NoError(t, err)
    assert.Equal(t, "Integration Test", decrypted.Name)
}
How It Works

ENCX uses a custom compact binary serializer that provides deterministic encryption with minimal overhead. The serialization is handled automatically by the generated code - you don't need to configure anything.

Validation

Validate your struct tags before generating code:

# Validate all Go files in current directory
encx-gen validate -v .

# Validate specific packages
encx-gen validate -v ./models ./api

# Validation is automatically run before generation
go run ./cmd/encx-gen generate -v .

Key Management

Key Rotation
// Rotate the Key Encryption Key (KEK)
if err := crypto.RotateKEK(ctx); err != nil {
    log.Fatalf("Key rotation failed: %v", err)
}

// Data encrypted with old keys can still be decrypted
// New encryptions will use the new key version
Multiple Key Versions

ENCX automatically handles multiple key versions:

// User encrypted with key version 1
oldUser := &User{Name: "Alice"}
oldUserEncx, _ := ProcessUserEncx(ctx, crypto, oldUser) // Uses current key (v1)

// Rotate key
crypto.RotateKEK(ctx)

// New user encrypted with key version 2
newUser := &User{Name: "Bob"}
newUserEncx, _ := ProcessUserEncx(ctx, crypto, newUser) // Uses current key (v2)

// Both can be decrypted regardless of key version
DecryptUserEncx(ctx, crypto, oldUserEncx) // Automatically uses key v1
DecryptUserEncx(ctx, crypto, newUserEncx) // Automatically uses key v2

KMS Providers

AWS KMS
import "github.com/hengadev/encx/providers/awskms"

kmsService, err := awskms.New(ctx, awskms.Config{
    Region: "us-east-1",
})
if err != nil {
    log.Fatal(err)
}

pepper := []byte("your-32-byte-pepper-here!!!!")
crypto, err := encx.NewCrypto(ctx,
    encx.WithKMSService(kmsService),
    encx.WithKEKAlias("alias/my-encryption-key"),
    encx.WithPepper(pepper),
)

→ Full AWS KMS Documentation

HashiCorp Vault
import "github.com/hengadev/encx/providers/hashicorpvault"

vaultClient, err := vault.NewClient(&vault.Config{
    Address: "https://vault.example.com",
})
if err != nil {
    log.Fatal(err)
}

kmsService, err := hashicorpvault.NewKMSService(vaultClient)
if err != nil {
    log.Fatal(err)
}

pepper := []byte("your-32-byte-pepper-here!!!!")
crypto, err := encx.NewCrypto(ctx,
    encx.WithKMSService(kmsService),
    encx.WithKEKAlias("transit/keys/my-key"),
    encx.WithPepper(pepper),
)

→ Full HashiCorp Vault Documentation

Examples

S3 Streaming Upload with Encryption

Example showing how to encrypt files on-the-fly and stream them directly to AWS S3:

import (
    "github.com/hengadev/encx"
    "github.com/hengadev/encx/providers/awskms"
    "github.com/aws/aws-sdk-go-v2/service/s3"
)

// Encrypt file and stream to S3
err := crypto.EncryptStream(ctx, fileReader, s3Writer, dek)

→ Full S3 Streaming Example

Features:

  • Zero-copy streaming encryption
  • Minimal memory usage (4KB buffer)
  • Production-ready with error handling
  • Includes HTTP upload server example

Best Practices

1. Use Combined Tags Strategically
// Good: Email needs both lookup and privacy
Email string `encx:"encrypt,hash_basic"`

// Good: Password needs auth and recovery
Password string `encx:"hash_secure,encrypt"`

// Avoid: Unnecessary combinations
InternalID string `encx:"encrypt,hash_basic,hash_secure"` // Too much
2. Proper Error Handling
userEncx, err := ProcessUserEncx(ctx, crypto, user)
if err != nil {
    // Log the error for debugging
    log.Printf("Encryption failed: %v", err)

    // Return user-friendly error
    return nil, fmt.Errorf("failed to process user data: %w", err)
}
3. Use Go Generate in Development
//go:generate encx-gen validate -v .
//go:generate go run ./cmd/encx-gen generate -v .

// Run validation and generation during development
// Run: go generate ./...
4. Handle Key Rotation Gracefully
// Schedule regular key rotation
go func() {
    ticker := time.NewTicker(30 * 24 * time.Hour) // 30 days
    defer ticker.Stop()
    
    for range ticker.C {
        if err := crypto.RotateKEK(ctx); err != nil {
            log.Printf("Key rotation failed: %v", err)
        }
    }
}()

Performance Considerations

  • Batch Operations: Process multiple structs in batches when possible
  • Connection Pooling: Use connection pooling for KMS and database
  • Caching: Consider caching decrypted DEKs for frequently accessed data
  • Monitoring: Monitor KMS API calls and database performance

Security Considerations

  • Pepper Management: Store pepper securely, separate from database
  • KMS Permissions: Use least-privilege access for KMS operations
  • Database Security: Encrypt database at rest and in transit
  • Memory Management: Clear sensitive data from memory when possible
  • Audit Logging: Log all cryptographic operations for compliance

Testing

The library includes comprehensive testing utilities:

// Unit testing with generated code
func TestUserEncryption(t *testing.T) {
    crypto, _ := encx.NewTestCrypto(t)

    user := &User{
        Email:    "test@example.com",
        Password: "secret123",
    }

    userEncx, err := ProcessUserEncx(ctx, crypto, user)
    assert.NoError(t, err)
    assert.NotEmpty(t, userEncx.EmailEncrypted)
    assert.NotEmpty(t, userEncx.EmailHash)
}

// Integration testing with full cycle
func TestUserEncryptDecryptCycle(t *testing.T) {
    crypto, _ := encx.NewTestCrypto(t)

    original := &User{Email: "integration@test.com"}
    userEncx, err := ProcessUserEncx(ctx, crypto, original)
    assert.NoError(t, err)

    decrypted, err := DecryptUserEncx(ctx, crypto, userEncx)
    assert.NoError(t, err)
    assert.Equal(t, original.Email, decrypted.Email)
}

Important: Version Control (.gitignore)

When using the encx package, add the following to your .gitignore:

.encx/

Contributing

  1. Fork the repository
  2. Create a feature branch
  3. Add tests for new functionality
  4. Run the validation utility: go run ./cmd/validate-tags -v
  5. Ensure all tests pass: go test ./...
  6. Submit a pull request

🚧 TODOs

  • implement example for different key management services:
    • HashiCorp Vault
    • AWS KMS
    • Azure Key Vault
    • Google Cloud KMS
    • Thales CipherTrust (formerly Vormetric)
    • AWS CloudHSM
  • explore concurrency for performance improvements
  • comprehensive tests
  • combined tags support
  • compile-time validation
  • enhanced error handling
  • improved documentation

License

[Add your license here]

Support

[Add support information here]

📚 Documentation

Complete Guides
Quick References
  • Use Cases: Data encryption, PII protection, searchable encryption, password management
  • Performance: Code generation provides 10x speed improvement over reflection
  • Security: AES-GCM encryption, Argon2id hashing, automatic key management
  • Integration: Works with PostgreSQL, SQLite, MySQL, AWS KMS, HashiCorp Vault

Context7 Quick Queries

For Context7 users, here are optimized query patterns:

Common Use Cases
Query Pattern Documentation Section
"encrypt user email golang" Quick Start + Context7 Guide
"password hashing with encryption" Advanced Examples + Context7 Guide
"database schema for encrypted fields" Context7 Guide
"performance optimization encryption" Code Generation Guide
"struct tag validation" Validation + API Reference
Implementation Patterns
Pattern Use Case Documentation
encx:"encrypt" Simple data protection Struct Tags Reference
encx:"hash_basic" Fast search/lookup Quick Start
encx:"hash_secure" Password security Advanced Examples
encx:"encrypt,hash_basic" Searchable encryption Combined Tags
Technology Integration
Technology Integration Guide
PostgreSQL Context7 Guide - Database
AWS KMS Configuration
HashiCorp Vault KMS Providers
Docker Complete Web App Example
Per-Struct Serializers Serializer Example

Documentation

Overview

Package encx provides production-ready field-level encryption, hashing, and key management for Go applications.

Context7 Metadata: - Library Type: Encryption & Security - Use Cases: Data protection, PII encryption, password hashing, searchable encryption - Complexity: Intermediate to Advanced - Performance: High (10x improvement with code generation) - Compliance: HIPAA, GDPR, SOX ready - Integration: PostgreSQL, MySQL, SQLite, AWS KMS, HashiCorp Vault

ENCX enables you to encrypt and hash struct fields using simple struct tags, with automatic key management through a DEK/KEK architecture. It supports multiple KMS backends, key rotation, combined operations, and comprehensive testing utilities.

Key Features

  • Field-level encryption with AES-GCM
  • Secure hashing with Argon2id and basic SHA-256
  • Combined operations - encrypt AND hash the same field
  • Automatic key management with DEK/KEK architecture
  • Key rotation support with version tracking
  • Multiple KMS backends (AWS KMS, HashiCorp Vault, etc.)
  • Comprehensive testing utilities and mocks
  • Compile-time validation for struct tags

Quick Start

Define your struct with encx tags:

type User struct {
    Name     string `encx:"encrypt"`
    Email    string `encx:"hash_basic"`
    Password string `encx:"hash_secure"`

    // No companion fields needed! Code generation creates separate output struct
}

Generate type-safe functions (recommended approach):

//go:generate encx-gen generate .

Create crypto instance and process with generated functions:

crypto, _ := encx.NewTestCrypto(nil)
user := &User{
    Name:     "John Doe",
    Email:    "john@example.com",
    Password: "secret123",
}

// Use generated type-safe functions
userEncx, err := ProcessUserEncx(ctx, crypto, user)
orderEncx, err := ProcessOrderEncx(ctx, crypto, order)
// Pattern: Process{YourStructName}Encx

Struct Tags

Single operation tags:

  • encx:"encrypt" - Encrypts field value
  • encx:"hash_basic" - Creates SHA-256 hash for searchable indexing
  • encx:"hash_secure" - Creates Argon2id hash with pepper (for passwords)

Combined operation tags:

  • encx:"encrypt,hash_basic" - Both encrypts AND hashes the field (searchable encryption)
  • encx:"hash_secure,encrypt" - Secure hash for auth + encryption for recovery

Code Generation

Code generation creates a separate {StructName}Encx struct with all encrypted/hashed fields:

// Your source struct
type User struct {
    Email string `encx:"encrypt,hash_basic"`
}

// Generated UserEncx struct (automatic)
type UserEncx struct {
    EmailEncrypted []byte
    EmailHash      string
    DEKEncrypted   []byte
    KeyVersion     int
    Metadata       string
}

Advanced Example: Combined Tags

Perfect for user lookup with privacy protection:

type User struct {
    Email string `encx:"encrypt,hash_basic"`

    // No companion fields needed! Code generation creates:
    // - UserEncx.EmailEncrypted []byte (for secure storage)
    // - UserEncx.EmailHash string (for fast lookups)
}

// Usage
user := &User{Email: "user@example.com"}
userEncx, err := ProcessUserEncx(ctx, crypto, user)

// Now you can:
// 1. Store userEncx.EmailEncrypted securely in database
// 2. Use userEncx.EmailHash for fast user lookups
// 3. Decrypt with DecryptUserEncx when needed for display

Production Configuration

// With AWS KMS
crypto, err := encx.NewCrypto(ctx,
    encx.WithKMSService(awsKMS),
    encx.WithDatabase(db),
    encx.WithPepper(pepper),
    encx.WithKEKAlias("myapp-kek"),
)

// With HashiCorp Vault
crypto, err := encx.NewCrypto(ctx,
    encx.WithKMSService(vaultKMS),
    encx.WithDatabase(db),
    encx.WithPepper(pepper),
    encx.WithKEKAlias("myapp-kek"),
)

Validation

Validate struct tags before generating code:

encx-gen validate -v .
encx-gen validate -v ./models ./api

Validation runs automatically before generation:

encx-gen generate -v .

Error Handling

ENCX provides structured error handling with sentinel errors for precise error classification:

user := &User{Name: "John", Email: "john@example.com"}
userEncx, err := ProcessUserEncx(ctx, crypto, user)
if err != nil {
    switch {
    case encx.IsRetryableError(err):
        // KMS or database temporarily unavailable - retry with backoff
        log.Warn("Retryable error: %v", err)
        return handleRetry(err)

    case encx.IsConfigurationError(err):
        // Invalid configuration - fix setup
        log.Error("Configuration error: %v", err)
        return handleConfigError(err)

    case encx.IsAuthError(err):
        // Authentication failed - check credentials
        log.Error("Authentication failed: %v", err)
        return handleAuthError(err)

    case encx.IsOperationError(err):
        // Encryption/decryption failed - check data/keys
        log.Error("Operation failed: %v", err)
        return handleOperationError(err)

    case encx.IsValidationError(err):
        // Data validation failed - check input
        log.Error("Validation error: %v", err)
        return handleValidationError(err)

    default:
        log.Error("Unknown error: %v", err)
        return err
    }
}

Checking specific errors:

if errors.Is(err, encx.ErrKMSUnavailable) {
    // Implement retry logic
    return retryWithBackoff(operation)
}

if errors.Is(err, encx.ErrAuthenticationFailed) {
    // Refresh credentials and retry
    return refreshAuthAndRetry(operation)
}

Testing

Unit testing with generated functions:

func TestUserEncryption(t *testing.T) {
    crypto, _ := encx.NewTestCrypto(t)

    user := &User{Email: "test@example.com"}
    userEncx, err := ProcessUserEncx(ctx, crypto, user)

    assert.NoError(t, err)
    assert.NotEmpty(t, userEncx.EmailEncrypted)
}

Integration testing with full cycle:

func TestUserEncryptDecryptCycle(t *testing.T) {
    crypto, _ := encx.NewTestCrypto(t)

    original := &User{Email: "test@example.com"}
    userEncx, err := ProcessUserEncx(ctx, crypto, original)
    assert.NoError(t, err)

    decrypted, err := DecryptUserEncx(ctx, crypto, userEncx)
    assert.NoError(t, err)
    assert.Equal(t, original.Email, decrypted.Email)
}

Documentation

For comprehensive documentation, examples, and advanced usage:

  • README.md - Complete getting started guide
  • docs/EXAMPLES.md - Detailed examples for all use cases
  • docs/API.md - Complete API reference
  • docs/MIGRATION.md - Version upgrade guide
  • docs/TROUBLESHOOTING.md - Common issues and solutions

Important: Version Control

Add to your .gitignore:

.encx/

Index

Constants

View Source
const (
	FieldKeyVersion   = "KeyVersion"
	FieldDEK          = "DEK"
	FieldDEKEncrypted = FieldDEK + SuffixEncrypted
)

Field name constants - exported for public use

View Source
const (
	SuffixEncrypted = "Encrypted"
	SuffixHashed    = "Hash"
)

Suffix constants for generated fields

View Source
const (
	StructTag     = "encx"
	TagEncrypt    = "encrypt"
	TagHashSecure = "hash_secure"
	TagHashBasic  = "hash_basic"
)

Tag constants for struct field annotations

View Source
const (
	Unknown    = types.Unknown
	BasicHash  = types.BasicHash
	SecureHash = types.SecureHash
	Encrypt    = types.Encrypt
	Decrypt    = types.Decrypt
)

Action constants

View Source
const Version = "1.0.0"

Version of the encx library

Variables

View Source
var (
	// High-level service errors
	ErrKMSUnavailable       = errors.New("KMS service unavailable")
	ErrKeyRotationRequired  = errors.New("key rotation required")
	ErrInvalidConfiguration = errors.New("invalid configuration")
	ErrAuthenticationFailed = errors.New("authentication failed")
	ErrEncryptionFailed     = errors.New("encryption failed")
	ErrDecryptionFailed     = errors.New("decryption failed")
	ErrDatabaseUnavailable  = errors.New("database unavailable")

	// Crypto errors
	ErrUninitializedPepper = errors.New("pepper value appears to be uninitialized (all zeros)")

	// Field errors
	ErrMissingField       = errors.New("missing required field")
	ErrMissingTargetField = errors.New("missing required target field")
	ErrInvalidFieldType   = errors.New("invalid field type")
	ErrUnsupportedType    = errors.New("unsupported type")

	// Conversion errors
	ErrTypeConversion = errors.New("type conversion failed")
	ErrNilPointer     = errors.New("nil pointer encountered")

	// Operation errors
	ErrOperationFailed = errors.New("operation failed")
	ErrInvalidFormat   = errors.New("invalid format")

	// Metadata validation errors
	ErrMissingKEKAlias         = errors.New("KEK alias is required")
	ErrMissingGeneratorVersion = errors.New("generator version is required")
)
View Source
var (
	NewInMemoryMetricsCollector   = monitoring.NewInMemoryMetricsCollector
	NewLoggingObservabilityHook   = monitoring.NewLoggingObservabilityHook
	NewMetricsObservabilityHook   = monitoring.NewMetricsObservabilityHook
	NewCompositeObservabilityHook = monitoring.NewCompositeObservabilityHook
)

Constructor functions

View Source
var (
	NoOpMetricsCollector  = &monitoring.NoOpMetricsCollector{}
	NoOpObservabilityHook = &monitoring.NoOpObservabilityHook{}
)

Default implementations

View Source
var (
	WithKMSService            = config.WithKMSService
	WithKEKAlias              = config.WithKEKAlias
	WithPepper                = config.WithPepper
	WithPepperSecretPath      = config.WithPepperSecretPath
	WithArgon2Params          = config.WithArgon2Params
	WithKeyMetadataDB         = config.WithKeyMetadataDB
	WithDBPath                = config.WithDBPath
	WithDBFilename            = config.WithDBFilename
	WithKeyMetadataDBPath     = config.WithKeyMetadataDBPath
	WithKeyMetadataDBFilename = config.WithKeyMetadataDBFilename
	WithMetricsCollector      = config.WithMetricsCollector
	WithObservabilityHook     = config.WithObservabilityHook
)

Configuration option functions

View Source
var (
	DefaultConfig = config.DefaultConfig
	ApplyOptions  = config.ApplyOptions
)

Helper functions

View Source
var (
	GitCommit string
	BuildDate string
	BuildUser string
)

Build information (set by ldflags during build)

View Source
var DefaultArgon2Params = &Argon2Params{
	Memory:      64 * 1024,
	Iterations:  3,
	Parallelism: 2,
	SaltLength:  16,
	KeyLength:   32,
}

DefaultArgon2Params provides secure default parameters

Functions

func DeserializeValue

func DeserializeValue(data []byte, target any) error

DeserializeValue converts bytes back to a value using ENCX's compact binary format. The target parameter must be a pointer to the type you want to deserialize into.

Example:

var result string
err := encx.DeserializeValue(data, &result)
if err != nil {
    // handle error
}

func IsAuthError

func IsAuthError(err error) bool

IsAuthError returns true if the error represents an authentication problem.

func IsConfigurationError

func IsConfigurationError(err error) bool

IsConfigurationError returns true if the error represents a configuration problem.

func IsOperationError

func IsOperationError(err error) bool

IsOperationError returns true if the error represents a failure during encryption/decryption operations.

func IsRetryableError

func IsRetryableError(err error) bool

IsRetryableError returns true if the error represents a transient failure that might succeed on retry.

func IsValidationError

func IsValidationError(err error) bool

IsValidationError returns true if the error represents a data validation problem.

func NewInvalidFieldTypeError

func NewInvalidFieldTypeError(fieldName string, expectedType, actualType string, action types.Action) error

func NewInvalidFormatError

func NewInvalidFormatError(fieldName string, formatName string, action types.Action) error

func NewMissingFieldError

func NewMissingFieldError(fieldName string, action types.Action) error

func NewMissingTargetFieldError

func NewMissingTargetFieldError(fieldName string, targetFieldName string, action types.Action) error

func NewNilPointerError

func NewNilPointerError(fieldName string, action types.Action) error

func NewOperationFailedError

func NewOperationFailedError(fieldName string, action types.Action, details string) error

func NewSimpleTestKMS

func NewSimpleTestKMS() config.KeyManagementService

NewSimpleTestKMS creates a new simple test KMS with a default key

func NewTypeConversionError

func NewTypeConversionError(fieldName string, typeName string, action types.Action) error

func NewUninitalizedPepperError

func NewUninitalizedPepperError() error

func NewUnsupportedTypeError

func NewUnsupportedTypeError(fieldName string, typeName string, action types.Action) error

func SerializeValue

func SerializeValue(value any) ([]byte, error)

SerializeValue converts a value to bytes using ENCX's compact binary format. This is the same serialization used internally by ENCX for field encryption. Applications can use this function to create consistent hash values for database queries.

Supported types: string, int, int32, int64, uint, uint32, uint64, bool, time.Time, []byte, float32, float64

Example:

data, err := encx.SerializeValue("hello world")
if err != nil {
    // handle error
}

func VersionInfo

func VersionInfo() string

VersionInfo returns formatted version information

Types

type Action

type Action = types.Action

Type aliases

type Argon2Params

type Argon2Params = config.Argon2Params

Argon2Params defines the parameters for Argon2id (re-exported from internal)

func NewArgon2Params

func NewArgon2Params(
	memory uint32,
	iterations uint32,
	parallelism uint8,
	saltLength uint32,
	keyLength uint32,
) (*Argon2Params, error)

NewArgon2Params creates a new Argon2Params instance with validation

type Config

type Config = config.Config

Type aliases

type Crypto

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

func NewCrypto

func NewCrypto(ctx context.Context, options ...Option) (*Crypto, error)

NewCrypto creates a new Crypto instance

func NewTestCrypto

func NewTestCrypto(t interface{}) (*Crypto, error)

NewTestCrypto creates a simple Crypto instance for testing and examples If t is nil, creates a basic test crypto for examples/demos

func (*Crypto) CompareBasicHashAndValue

func (c *Crypto) CompareBasicHashAndValue(ctx context.Context, value any, hashValue string) (bool, error)

func (*Crypto) CompareSecureHashAndValue

func (c *Crypto) CompareSecureHashAndValue(ctx context.Context, value any, hashValue string) (bool, error)

func (*Crypto) DecryptDEKWithVersion

func (c *Crypto) DecryptDEKWithVersion(ctx context.Context, ciphertextDEK []byte, kekVersion int) ([]byte, error)

func (*Crypto) DecryptData

func (c *Crypto) DecryptData(ctx context.Context, ciphertext []byte, dek []byte) ([]byte, error)

func (*Crypto) DecryptStream

func (c *Crypto) DecryptStream(ctx context.Context, reader io.Reader, writer io.Writer, dek []byte) error

func (*Crypto) EncryptDEK

func (c *Crypto) EncryptDEK(ctx context.Context, plaintextDEK []byte) ([]byte, error)

func (*Crypto) EncryptData

func (c *Crypto) EncryptData(ctx context.Context, plaintext []byte, dek []byte) ([]byte, error)

func (*Crypto) EncryptStream

func (c *Crypto) EncryptStream(ctx context.Context, reader io.Reader, writer io.Writer, dek []byte) error

func (*Crypto) GenerateDEK

func (c *Crypto) GenerateDEK() ([]byte, error)

func (*Crypto) GetAlias

func (c *Crypto) GetAlias() string

func (*Crypto) GetArgon2Params

func (c *Crypto) GetArgon2Params() *Argon2Params

func (*Crypto) GetCurrentKEKVersion

func (c *Crypto) GetCurrentKEKVersion(ctx context.Context, alias string) (int, error)

Internal interface implementations

func (*Crypto) GetKMSKeyIDForVersion

func (c *Crypto) GetKMSKeyIDForVersion(ctx context.Context, alias string, version int) (string, error)

func (*Crypto) GetPepper

func (c *Crypto) GetPepper() []byte

Getter methods

func (*Crypto) HashBasic

func (c *Crypto) HashBasic(ctx context.Context, value []byte) string

func (*Crypto) HashSecure

func (c *Crypto) HashSecure(ctx context.Context, value []byte) (string, error)

func (*Crypto) RotateKEK

func (c *Crypto) RotateKEK(ctx context.Context) error

type CryptoService

type CryptoService interface {
	GetPepper() []byte
	GetArgon2Params() *Argon2Params
	GetAlias() string
	GenerateDEK() ([]byte, error)
	EncryptData(ctx context.Context, plaintext []byte, dek []byte) ([]byte, error)
	DecryptData(ctx context.Context, ciphertext []byte, dek []byte) ([]byte, error)
	EncryptDEK(ctx context.Context, plaintextDEK []byte) ([]byte, error)
	DecryptDEKWithVersion(ctx context.Context, ciphertextDEK []byte, kekVersion int) ([]byte, error)
	RotateKEK(ctx context.Context) error
	HashBasic(ctx context.Context, value []byte) string
	HashSecure(ctx context.Context, value []byte) (string, error)
	CompareSecureHashAndValue(ctx context.Context, value any, hashValue string) (bool, error)
	CompareBasicHashAndValue(ctx context.Context, value any, hashValue string) (bool, error)
	EncryptStream(ctx context.Context, reader io.Reader, writer io.Writer, dek []byte) error
	DecryptStream(ctx context.Context, reader io.Reader, writer io.Writer, dek []byte) error
	GetCurrentKEKVersion(ctx context.Context, alias string) (int, error)
	GetKMSKeyIDForVersion(ctx context.Context, alias string, version int) (string, error)
}

type EncryptionMetadata

type EncryptionMetadata struct {
	PepperVersion    int    `json:"pepper_version"`
	KEKAlias         string `json:"kek_alias"`
	EncryptionTime   int64  `json:"encryption_time"`
	GeneratorVersion string `json:"generator_version"`
}

EncryptionMetadata contains metadata about how a struct was encrypted

func NewEncryptionMetadata

func NewEncryptionMetadata(kekAlias, generatorVersion string, pepperVersion int) *EncryptionMetadata

NewEncryptionMetadata creates a new EncryptionMetadata instance

func (*EncryptionMetadata) FromJSON

func (em *EncryptionMetadata) FromJSON(data []byte) error

FromJSON deserializes metadata from JSON bytes

func (*EncryptionMetadata) ToJSON

func (em *EncryptionMetadata) ToJSON() ([]byte, error)

ToJSON serializes the metadata to JSON bytes

func (*EncryptionMetadata) Validate

func (em *EncryptionMetadata) Validate() error

Validate checks if the metadata is valid

type KeyManagementService

type KeyManagementService = config.KeyManagementService

Interface aliases

type MetricsCollector

type MetricsCollector = monitoring.MetricsCollector

Type aliases

type ObservabilityHook

type ObservabilityHook = monitoring.ObservabilityHook

Type aliases

type Option

type Option = config.Option

Type aliases

type SimpleTestKMS

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

SimpleTestKMS implements a basic in-memory KMS for testing and examples

func (*SimpleTestKMS) CreateKey

func (s *SimpleTestKMS) CreateKey(ctx context.Context, description string) (string, error)

CreateKey creates a new test key and returns its ID

func (*SimpleTestKMS) DecryptDEK

func (s *SimpleTestKMS) DecryptDEK(ctx context.Context, keyID string, ciphertext []byte) ([]byte, error)

DecryptDEK decrypts the DEK using AES-GCM

func (*SimpleTestKMS) EncryptDEK

func (s *SimpleTestKMS) EncryptDEK(ctx context.Context, keyID string, plaintext []byte) ([]byte, error)

EncryptDEK encrypts the DEK using AES-GCM

func (*SimpleTestKMS) GetKeyID

func (s *SimpleTestKMS) GetKeyID(ctx context.Context, alias string) (string, error)

GetKeyID returns a test key ID for the given alias

type VersionDetails

type VersionDetails struct {
	Version   string `json:"version"`
	GitCommit string `json:"git_commit,omitempty"`
	BuildDate string `json:"build_date,omitempty"`
	BuildUser string `json:"build_user,omitempty"`
}

VersionDetails contains detailed version information

func FullVersionInfo

func FullVersionInfo() VersionDetails

FullVersionInfo returns complete version information including build user

func (VersionDetails) String

func (v VersionDetails) String() string

String returns a formatted version string

Directories

Path Synopsis
cmd
encx-gen command
Package examples demonstrates various use cases for the encx library.
Package examples demonstrates various use cases for the encx library.
basic_demo command
error_handling command
go_generate_demo
Package go_generate_demo demonstrates encx-gen integration
Package go_generate_demo demonstrates encx-gen integration
internal
providers
awskms
Package awskms provides AWS Key Management Service (KMS) integration for encx.
Package awskms provides AWS Key Management Service (KMS) integration for encx.
test

Jump to

Keyboard shortcuts

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