Encryption & Hashing
λ Cosmos provides encryption and hashing implementations through the contract.Encrypter and contract.Hasher interfaces.
type Encrypter interface { Encrypt(value []byte) ([]byte, error) Decrypt(value []byte) ([]byte, error)}
type Hasher interface { Hash(value []byte) ([]byte, error) Check(value []byte, hash []byte) (bool, error)}Encryption
Section titled “Encryption”Both implementations use authenticated encryption (AEAD), which provides both confidentiality and integrity. The nonce is automatically generated and prepended to the ciphertext.
AES-GCM
Section titled “AES-GCM”import "github.com/studiolambda/cosmos/framework/crypto"
// Key must be 16, 24, or 32 bytes for AES-128, AES-192, or AES-256key := []byte("your-32-byte-secret-key-here!!!!") // 32 bytes = AES-256
enc, err := crypto.NewAES(key)if err != nil { log.Fatal(err)}
// Encryptciphertext, err := enc.Encrypt([]byte("sensitive data"))
// Decryptplaintext, err := enc.Decrypt(ciphertext)AES-GCM is the standard choice for most applications. Use AES-256 (32-byte key) for maximum security.
ChaCha20-Poly1305
Section titled “ChaCha20-Poly1305”import "github.com/studiolambda/cosmos/framework/crypto"
// Key must be exactly 32 byteskey := []byte("your-32-byte-secret-key-here!!!!")
enc, err := crypto.NewChaCha20(key)if err != nil { log.Fatal(err)}
ciphertext, err := enc.Encrypt([]byte("sensitive data"))plaintext, err := enc.Decrypt(ciphertext)ChaCha20-Poly1305 is an alternative to AES-GCM that performs better on hardware without AES instruction set support (e.g., older ARM devices). On modern x86 hardware with AES-NI, performance is comparable.
Choosing an Algorithm
Section titled “Choosing an Algorithm”| AES-GCM | ChaCha20-Poly1305 | |
|---|---|---|
| Key size | 16, 24, or 32 bytes | 32 bytes only |
| Hardware acceleration | AES-NI on x86 | Software-optimized |
| Best for | Servers with AES-NI | Mobile, embedded, or mixed hardware |
| Standard | NIST | IETF RFC 8439 |
Both are secure and widely used. AES-256-GCM is the most common choice for server applications.
Hashing
Section titled “Hashing”Argon2
Section titled “Argon2”The recommended choice for password hashing:
import "github.com/studiolambda/cosmos/framework/hash"
hasher := hash.NewArgon2()
// Hash a passwordhashed, err := hasher.Hash([]byte("user-password"))
// Verify a passwordok, err := hasher.Check([]byte("user-password"), hashed)if ok { // password matches}Customize the Argon2 parameters:
hasher := hash.NewArgon2With(hash.Argon2Config{ // Configure memory, iterations, parallelism, etc.})The default configuration uses argon2.DefaultConfig() which provides secure defaults suitable for most applications.
Bcrypt
Section titled “Bcrypt”A well-established alternative:
import "github.com/studiolambda/cosmos/framework/hash"
hasher := hash.NewBcrypt()
hashed, err := hasher.Hash([]byte("user-password"))ok, err := hasher.Check([]byte("user-password"), hashed)Customize the cost factor:
hasher := hash.NewBcryptWith(hash.BcryptOptions{ cost: 12, // default is 10})Higher cost means slower hashing, which is more resistant to brute force attacks but increases CPU usage during authentication.
Choosing an Algorithm
Section titled “Choosing an Algorithm”| Argon2 | Bcrypt | |
|---|---|---|
| Memory-hard | Yes | No |
| GPU resistance | High | Moderate |
| Configurable | Memory, time, parallelism | Cost factor only |
| Recommended | Yes (modern standard) | Yes (proven, widely supported) |
Argon2 is the winner of the Password Hashing Competition and is recommended for new applications. Bcrypt remains a solid choice and is well-supported across ecosystems if you need interoperability.
Using with Middleware
Section titled “Using with Middleware”Inject encryption or hashing instances into the request context:
app.Use(middleware.Provide(encKey, encrypter))app.Use(middleware.Provide(hashKey, hasher))
func register(w http.ResponseWriter, r *http.Request) error { h := r.Context().Value(hashKey).(contract.Hasher)
body, err := request.JSON[RegisterRequest](r) if err != nil { return err }
hashed, err := h.Hash([]byte(body.Password)) if err != nil { return err }
// Store hashed password...}