Skip to main content

Password

The password package provides pluggable password encoding with a composite encoder that supports multiple algorithms simultaneously.

Encoder Interface

type Encoder interface {
Encode(password string) (string, error)
Matches(password, encodedPassword string) bool
UpgradeEncoding(encodedPassword string) bool
}

Composite Encoder

The composite encoder stores the algorithm identifier as a prefix in the encoded password, enabling seamless algorithm migration:

import "github.com/coldsmirk/vef-framework-go/password"

encoder := password.NewCompositeEncoder(
password.Bcrypt, // default for new passwords
map[password.EncoderID]password.Encoder{
password.Bcrypt: password.NewBcryptEncoder(),
password.Argon2: password.NewArgon2Encoder(),
password.Scrypt: password.NewScryptEncoder(),
password.SHA256: password.NewSHA256Encoder(),
},
)

Encoding

encoded, err := encoder.Encode("my-password")
// → "{bcrypt}$2a$10$..."

Matching

The encoder automatically detects the algorithm from the {prefix}:

// Matches against any supported algorithm
ok := encoder.Matches("my-password", "{bcrypt}$2a$10$...") // true
ok := encoder.Matches("my-password", "{argon2}$argon2id$...") // true
ok := encoder.Matches("my-password", "{sha256}abc123...") // true

Upgrade Detection

Check if a password needs re-encoding (e.g., when migrating from SHA256 to bcrypt):

needsUpgrade := encoder.UpgradeEncoding("{sha256}abc123...")
// → true (because default is bcrypt, not sha256)

Available Encoders

Encoder IDConstructorSecurity Level
password.BcryptNewBcryptEncoder()⭐⭐⭐⭐ Recommended
password.Argon2NewArgon2Encoder()⭐⭐⭐⭐⭐ Strongest
password.ScryptNewScryptEncoder()⭐⭐⭐⭐ Strong
password.SHA256NewSHA256Encoder()⭐⭐ Legacy only
password.PlaintextNewPlaintextEncoder()⭐ Testing only

Password Format

Encoded passwords follow the format: {algorithm}encoded_value

{bcrypt}$2a$10$N9qo8uLOickgx2ZMRZoMyeIjZAgcfl7p92ldGxad68LJZdL17lhWy
{argon2}$argon2id$v=19$m=65536,t=3,p=4$c29tZXNhbHQ$...
{sha256}5e884898da28047151d0e56f8dc6292773603d0d6aabbdd62a11ef721d1542d8