Go
Server-side encryption middleware for Go. Automatically decrypts incoming requests and encrypts outgoing responses using the v2 ECDH flow. Provides seamless integration with standard net/http.
Quick Start
1. Install the Package
Install the Ciph Go module inside your project:
go get github.com/Eularix/ciph/modules/ciph-go/middleware2. Generate Key Pair
The Go backend requires a PKCS8 P-256 private key. You can generate one using the built-in CLI:
go run github.com/Eularix/ciph/modules/ciph-go/cmd/generate-keys@latestThis will generate a .env format output with CIPH_PRIVATE_KEY for your backend and CIPH_PUBLIC_KEY for your frontend.
3. Mount the Middleware
Wrap your http.ServeMux or http.Handler with the Ciph middleware:
package main
import (
"encoding/json"
"log"
"net/http"
"os"
"github.com/Eularix/ciph/modules/ciph-go/middleware"
)
func main() {
// 1. Initialize Configuration
config := &middleware.Config{
PrivateKey: os.Getenv("CIPH_PRIVATE_KEY"),
StrictFingerprint: true, // Validates User-Agent for added security
MaxPayloadSize: 10 * 1024 * 1024, // 10MB
ExcludeRoutes: []string{"/health", "/ciph-public-key", "/ciph", "/ciph/*"},
}
ciphMw, err := middleware.New(config)
if err != nil {
log.Fatalf("Failed to initialize Ciph middleware: %v", err)
}
mux := http.NewServeMux()
// 2. Add Handlers
mux.HandleFunc("/api/users", func(w http.ResponseWriter, r *http.Request) {
// Request body is automatically decrypted
var data map[string]interface{}
json.NewDecoder(r.Body).Decode(&data)
// Response will be automatically encrypted
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(map[string]interface{}{"status": "success"})
})
// 3. Wrap Mux with Middleware
encryptedHandler := ciphMw.Wrap(mux)
log.Printf("Server starting on :3001")
http.ListenAndServe(":3001", encryptedHandler)
}The actual public key must be shared with the frontend. The middleware automatically handles serving the public key at the /ciph-public-key endpoint to simplify key rotation.
Configuration Options
When setting up middleware.Config, you can provide these options:
type Config struct {
// Base64url-encoded P-256 private key (PKCS8) - REQUIRED
PrivateKey string
// Routes that bypass encryption entirely. Supports exact matches and wildcards (/*).
// Default: ["/health", "/ciph-public-key", "/ciph", "/ciph/*"]
ExcludeRoutes []string
// Validates the User-Agent signature.
// Default: true
StrictFingerprint bool
// Maximum allowed payload size in bytes.
// Default: 10485760 (10MB)
MaxPayloadSize int64
// Allow unencrypted requests for migration purposes.
// Default: false
AllowUnencrypted bool
}Excluding Routes
To disable encryption on certain routes, (like webhooks or health checks), add them to the ExcludeRoutes config.
config := &middleware.Config{
PrivateKey: os.Getenv("CIPH_PRIVATE_KEY"),
ExcludeRoutes: []string{
"/health", // Exact match
"/webhooks/*", // Wildcard match for paths like /webhooks/stripe
},
}Routes added to ExcludeRoutes completely bypass the middleware. Ensure they are not used to process or receive sensitive plaintext data.
DevTools Inspector
Easily inspect incoming and outgoing encrypted traffic with the built-in Ciph DevTools. Because traffic from the frontend is encrypted natively, typical network debuggers will only show encrypted ciphertexts. The DevTools inspector displays the decrypted payloads in isolation for easy debugging during development.
// 1. Enable dev tools before setting up routes (specify max log count)
ciphMw.EnableDevTools(500)
// 2. Mount the DevTools UI and API under /ciph/
if devTools := ciphMw.GetDevToolsBuffer(); devTools != nil {
devtoolsHandler := ciphMw.RegisterDevToolsRoutes(devTools)
mux.Handle("/ciph", devtoolsHandler) // UI
mux.Handle("/ciph/logs", devtoolsHandler) // API
}Open http://localhost:3001/ciph in your browser.
Only enable the inspector in development environments. Do not call .EnableDevTools() in production.
How It Works
Request Flow (Decryption)
- Reads Headers — Obtains
X-Client-PublicKeyand the encryptedX-Fingerprintpayload. - Generates Shared Secret — Derives the shared secret via ECDH using the server's private key and checking the client's public key.
- Validates the Fingerprint — Compares the User-Agent locally against the fingerprint hash.
- Derives Key — Re-derives a one-time request AES-256-GCM key.
- Decrypts and Re-wraps Body — Performs AES decryption and overwrites the
http.Request.Bodyfor downstream handlers.
Response Flow (Encryption)
- Intercepts Response — The middleware buffers the response of standard handlers instead of writing them to the network.
- Encrypts Data — Uses the generated AES key to encrypt the entire buffered payload.
- Rewrites Wire Payload — Transmits
{ "status": "encrypted", "data": "..." }formatted data down to the client.