secure

package module
v1.1.0 Latest Latest
Warning

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

Go to latest
Published: Jan 27, 2026 License: Apache-2.0 Imports: 18 Imported by: 4

README

secure-kit

Go Reference Go Report Card License codecov

中文文档

A unified cryptographic toolkit for Go services. This package provides hash functions (Argon2, bcrypt, SHA, MD5), secure random number generation, constant-time comparison, and sensitive data masking utilities.

Features

  • Multiple Hash Algorithms: Argon2id, bcrypt, SHA-256, SHA-512, MD5 with unified interface
  • Secure Random: Cryptographically secure random bytes, strings, digits, tokens, and UUIDs
  • Timing Attack Prevention: Constant-time comparison functions
  • Data Masking: Email, phone, credit card, IP address, API key masking for logging
  • Zero External Dependencies: Only uses Go standard library and golang.org/x/crypto

Installation

go get github.com/soulteary/secure-kit

Usage

Hash Interface

All hashers implement the unified Hasher interface:

type Hasher interface {
    Hash(plaintext string) (string, error)
    Verify(hash, plaintext string) bool
    Algorithm() string
}
import secure "github.com/soulteary/secure-kit"

// Create with default parameters
hasher := secure.NewArgon2Hasher()

// Or with custom parameters
hasher := secure.NewArgon2Hasher(
    secure.WithArgon2Time(2),
    secure.WithArgon2Memory(64*1024),
    secure.WithArgon2Threads(4),
)

// Hash a password
hash, err := hasher.Hash("myPassword123!")
if err != nil {
    log.Fatal(err)
}

// Verify a password
if hasher.Verify(hash, "myPassword123!") {
    fmt.Println("Password matches!")
}

// PHC format (compatible with other implementations)
hash, err := hasher.HashWithParams("password")
// Output: $argon2id$v=19$m=65536,t=1,p=4$salt$hash
bcrypt
hasher := secure.NewBcryptHasher()

// Or with custom cost
hasher := secure.NewBcryptHasher(secure.WithBcryptCost(12))

hash, _ := hasher.Hash("password")
valid := hasher.Verify(hash, "password")
SHA-256/SHA-512
sha256Hasher := secure.NewSHA256Hasher()
sha512Hasher := secure.NewSHA512Hasher()

hash, _ := sha256Hasher.Hash("data")
valid := sha256Hasher.Verify(hash, "data")

// Helper functions
sha512Hash := secure.GetSHA512Hash("text")
sha256Hash := secure.GetSHA256Hash("text")
MD5 (Legacy Only)
// WARNING: MD5 is cryptographically broken. Use only for legacy compatibility.
hasher := secure.NewMD5Hasher()
hash, _ := hasher.Hash("data")

// Helper function
md5Hash := secure.GetMD5Hash("text")
Secure Random
// Random bytes
bytes, err := secure.RandomBytes(32)

// Random hex string
hex, err := secure.RandomHex(16) // Returns 32-char hex string

// Random Base64 strings
b64, err := secure.RandomBase64(32)
urlSafeB64, err := secure.RandomBase64URL(32)

// Random digits (for OTP codes)
code, err := secure.RandomDigits(6) // e.g., "847293"

// Random alphanumeric string
token, err := secure.RandomAlphanumeric(20)

// Random token (URL-safe base64)
token, err := secure.RandomToken(32)

// Random UUID (v4)
uuid, err := secure.RandomUUID() // e.g., "a1b2c3d4-e5f6-4a7b-8c9d-0e1f2a3b4c5d"

// Random integers
n, err := secure.RandomInt(100)           // [0, 100)
n, err := secure.RandomIntRange(10, 20)   // [10, 20]

// Custom charset
s, err := secure.RandomString(10, secure.CharsetAlphanumeric)
Constant-Time Comparison
// Prevent timing attacks when comparing sensitive values
if secure.ConstantTimeEqual(userInput, secretKey) {
    // Valid key
}

// Aliases for familiarity
secure.SecureCompare(a, b)
secure.TimingSafeEqual(a, b)
secure.ConstantTimeEqualBytes([]byte(a), []byte(b))
Data Masking
// Email masking
secure.MaskEmail("user@example.com")        // "u***@example.com"
secure.MaskEmailPartial("john@example.com") // "jo***@example.com"

// Phone masking
secure.MaskPhone("13812345678")      // "138****5678"
secure.MaskPhoneSimple("+1234567890") // "+12***7890"

// Credit card masking
secure.MaskCreditCard("4111111111111111")    // "************1111"
secure.MaskCreditCard("4111-1111-1111-1111") // "****-****-****-1111"

// IP address masking
secure.MaskIPAddress("192.168.1.100") // "192.*.*.*"
secure.MaskIPAddress("2001:db8::1")   // "2001:****:****:..."

// API key masking
secure.MaskAPIKey("sk_live_abcdefghijklmnop") // "sk_l***mnop"

// Name masking
secure.MaskName("John Doe") // "J*** D***"

// Generic string masking
secure.MaskString("1234567890", 3) // "123***890"

// Truncation
secure.TruncateString("long text here", 8) // "long tex..."
Drop-in Resolvers (Stargate Compatibility)

For backward compatibility with existing code:

// These implement the HashResolver interface
var resolver secure.HashResolver

resolver = &secure.BcryptResolver{}
resolver = &secure.SHA512Resolver{}
resolver = &secure.MD5Resolver{}
resolver = &secure.PlaintextResolver{}

// Usage
if resolver.Check(storedHash, userPassword) {
    // Valid password
}

Project Structure

secure-kit/
├── interface.go      # Hasher and HashResolver interfaces
├── argon2.go         # Argon2id implementation
├── bcrypt.go         # bcrypt implementation
├── sha.go            # SHA-256/SHA-512 implementation
├── md5.go            # MD5 implementation (legacy)
├── plaintext.go      # Plaintext comparison (testing only)
├── compare.go        # Constant-time comparison
├── random.go         # Secure random generation
├── mask.go           # Sensitive data masking
└── *_test.go         # Comprehensive tests

Security Recommendations

Use Case Recommended Algorithm
Password hashing Argon2id or bcrypt
OTP/verification codes Argon2id
API tokens RandomToken + constant-time compare
Checksums SHA-256 or SHA-512
Legacy systems MD5 (migration to Argon2 recommended)

Never use SHA-256, SHA-512, or MD5 for password hashing. These are fast hashes designed for integrity checks, not password security.

Integration Example

Herald (OTP Service)
import secure "github.com/soulteary/secure-kit"

// Generate OTP code
code, _ := secure.RandomDigits(6)

// Hash for storage
hasher := secure.NewArgon2Hasher()
hash, _ := hasher.Hash(code)

// Store hash in Redis, send code via SMS/email

// Later, verify user input
if hasher.Verify(storedHash, userInputCode) {
    // Valid OTP
}
Stargate (Auth Gateway)
import secure "github.com/soulteary/secure-kit"

// Verify password with multiple algorithms
resolvers := map[string]secure.HashResolver{
    "bcrypt":    &secure.BcryptResolver{},
    "sha512":    &secure.SHA512Resolver{},
    "md5":       &secure.MD5Resolver{},
    "plaintext": &secure.PlaintextResolver{},
}

func verifyPassword(algorithm, hash, password string) bool {
    resolver, ok := resolvers[algorithm]
    if !ok {
        return false
    }
    return resolver.Check(hash, password)
}

Requirements

  • Go 1.25 or later
  • golang.org/x/crypto (for Argon2 and bcrypt)

Test Coverage

Run tests:

go test ./... -v

# With coverage
go test ./... -coverprofile=coverage.out -covermode=atomic
go tool cover -html=coverage.out -o coverage.html
go tool cover -func=coverage.out

Benchmarks

go test -bench=. -benchmem

Contributing

  1. Fork the repository
  2. Create your feature branch (git checkout -b feature/amazing-feature)
  3. Commit your changes (git commit -m 'Add some amazing feature')
  4. Push to the branch (git push origin feature/amazing-feature)
  5. Open a Pull Request

License

See LICENSE file for details.

Documentation

Overview

Package secure provides unified cryptographic hash functions, secure random number generation, and sensitive data masking utilities for Go services.

This package supports multiple hash algorithms with a unified interface:

  • Argon2id: Recommended for password hashing and OTP codes (memory-hard)
  • bcrypt: Industry standard for password hashing
  • SHA-256/SHA-512: Fast hashing for checksums and message authentication
  • MD5: Legacy support only (NOT recommended for new implementations)

All hash functions implement the Hasher interface, enabling consistent usage across different algorithms and easy algorithm switching.

Index

Constants

View Source
const (
	DefaultArgon2Time    = 1         // Number of iterations
	DefaultArgon2Memory  = 64 * 1024 // 64 MB
	DefaultArgon2Threads = 4         // Parallelism
	DefaultArgon2KeyLen  = 32        // 256 bits
	DefaultArgon2SaltLen = 16        // 128 bits
)

Default Argon2 parameters These are recommended values for most use cases. For high-security applications, consider increasing memory and iterations.

View Source
const (
	// CharsetAlphanumeric contains lowercase, uppercase letters and digits
	CharsetAlphanumeric = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"

	// CharsetAlphanumericLower contains lowercase letters and digits
	CharsetAlphanumericLower = "abcdefghijklmnopqrstuvwxyz0123456789"

	// CharsetAlphanumericUpper contains uppercase letters and digits
	CharsetAlphanumericUpper = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"

	// CharsetDigits contains only digits
	CharsetDigits = "0123456789"

	// CharsetHex contains hexadecimal characters (lowercase)
	CharsetHex = "0123456789abcdef"

	// CharsetAlpha contains only letters (lowercase and uppercase)
	CharsetAlpha = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"

	// CharsetURLSafe contains URL-safe characters
	CharsetURLSafe = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_"
)

Common character sets for RandomString

View Source
const DefaultBcryptCost = bcrypt.DefaultCost // 10

Default bcrypt cost factor The cost factor determines the computational cost of hashing. A value of 10 is a reasonable default; increase for higher security.

Variables

This section is empty.

Functions

func ComputeHMACSHA1 added in v1.1.0

func ComputeHMACSHA1(payload []byte, secret string) string

ComputeHMACSHA1 computes HMAC-SHA1 for the given payload and secret. Returns the signature as a lowercase hex string.

func ComputeHMACSHA256 added in v1.1.0

func ComputeHMACSHA256(payload []byte, secret string) string

ComputeHMACSHA256 computes HMAC-SHA256 for the given payload and secret. Returns the signature as a lowercase hex string.

func ComputeHMACSHA512 added in v1.1.0

func ComputeHMACSHA512(payload []byte, secret string) string

ComputeHMACSHA512 computes HMAC-SHA512 for the given payload and secret. Returns the signature as a lowercase hex string.

func ConstantTimeEqual

func ConstantTimeEqual(a, b string) bool

ConstantTimeEqual compares two strings in constant time to prevent timing attacks. This should be used when comparing sensitive values like API keys, tokens, or hashes.

Unlike simple == comparison, this function takes the same amount of time regardless of how many characters match, preventing attackers from learning information about the secret value through timing analysis.

func ConstantTimeEqualBytes

func ConstantTimeEqualBytes(a, b []byte) bool

ConstantTimeEqualBytes compares two byte slices in constant time.

func ExtractSignatures added in v1.1.0

func ExtractSignatures(source, prefix string) []string

ExtractSignatures extracts signatures from a comma-separated list. It also handles algorithm prefixes (e.g., "sha256=...").

func GetMD5Hash

func GetMD5Hash(text string) string

GetMD5Hash computes the MD5 hash of the given text. Returns the hash as a lowercase hex string. This is a helper function for backward compatibility with existing code.

WARNING: MD5 is cryptographically broken. Use only for legacy compatibility.

func GetSHA256Hash

func GetSHA256Hash(text string) string

GetSHA256Hash computes the SHA-256 hash of the given text. Returns the hash as a lowercase hex string.

func GetSHA512Hash

func GetSHA512Hash(text string) string

GetSHA512Hash computes the SHA-512 hash of the given text. Returns the hash as a lowercase hex string. This is a helper function for backward compatibility with existing code.

func MaskAPIKey

func MaskAPIKey(key string) string

MaskAPIKey masks an API key, showing only the first and last few characters.

Examples:

  • "sk_live_abcdefghijklmnop" -> "sk_l***mnop"
  • "key_1234567890" -> "key_***7890"

func MaskCreditCard

func MaskCreditCard(card string) string

MaskCreditCard masks a credit card number, showing only the last 4 digits.

Examples:

  • "4111111111111111" -> "************1111"
  • "4111-1111-1111-1111" -> "****-****-****-1111"

func MaskEmail

func MaskEmail(email string) string

MaskEmail masks an email address for logging/display purposes. Shows only the first character of the local part and the full domain.

Examples:

  • "user@example.com" -> "u***@example.com"
  • "test.user@example.com" -> "t***@example.com"
  • "a@example.com" -> "a***@example.com"

func MaskEmailPartial

func MaskEmailPartial(email string) string

MaskEmailPartial masks an email address, showing first 2 characters. This provides slightly more context while still protecting privacy.

Examples:

  • "john.doe@example.com" -> "jo***@example.com"
  • "user@example.com" -> "us***@example.com"

func MaskIPAddress

func MaskIPAddress(ip string) string

MaskIPAddress masks an IP address for logging/display purposes. For IPv4, shows only the first octet. For IPv6, shows only the first segment.

Examples:

  • "192.168.1.100" -> "192.*.*.*"
  • "2001:0db8:85a3:0000:0000:8a2e:0370:7334" -> "2001:****:****:****:****:****:****:****"

func MaskName

func MaskName(name string) string

MaskName masks a person's name for privacy. Shows only the first character of each word.

Examples:

  • "John Doe" -> "J*** D***"
  • "Alice" -> "A***"

func MaskPhone

func MaskPhone(phone string) string

MaskPhone masks a phone number for logging/display purposes. Shows only the first 3 and last 4 digits.

Examples:

  • "13812345678" -> "138****5678"
  • "+8613812345678" -> "+86****5678"
  • "1234567" -> "123****"

func MaskPhoneSimple

func MaskPhoneSimple(phone string) string

MaskPhoneSimple masks a phone number with a simpler format. Shows first 3 and last 4 characters with fixed *** in between.

Examples:

  • "+1234567890" -> "+12***7890"
  • "13812345678" -> "138***5678"

func MaskString

func MaskString(s string, visibleChars int) string

MaskString masks a string, showing only the first and last few characters.

Examples (with visibleChars=3):

  • "1234567890" -> "123***890"
  • "short" -> "***"

func MustRandomBytes

func MustRandomBytes(n int) []byte

MustRandomBytes is like RandomBytes but panics on error. Deprecated: Use RandomBytesOrPanic instead.

func RandomAlphanumeric

func RandomAlphanumeric(length int) (string, error)

RandomAlphanumeric generates a cryptographically secure random alphanumeric string.

func RandomBase64

func RandomBase64(n int) (string, error)

RandomBase64 generates a cryptographically secure random base64 string. Uses standard base64 encoding.

func RandomBase64URL

func RandomBase64URL(n int) (string, error)

RandomBase64URL generates a cryptographically secure random URL-safe base64 string. Uses URL-safe base64 encoding (no padding).

func RandomBytes

func RandomBytes(n int) ([]byte, error)

RandomBytes generates cryptographically secure random bytes. Uses crypto/rand which is suitable for security-sensitive applications.

func RandomBytesOrPanic

func RandomBytesOrPanic(n int) []byte

RandomBytesOrPanic is like RandomBytes but panics on error. Use only in initialization code where failure is unrecoverable.

func RandomDigits

func RandomDigits(length int) (string, error)

RandomDigits generates a cryptographically secure random string of digits. Commonly used for OTP/verification codes.

func RandomHex

func RandomHex(n int) (string, error)

RandomHex generates a cryptographically secure random hex string. The returned string will be 2*n characters long (each byte = 2 hex chars).

func RandomInt

func RandomInt(max int64) (int64, error)

RandomInt generates a cryptographically secure random integer in [0, max).

func RandomIntRange

func RandomIntRange(min, max int64) (int64, error)

RandomIntRange generates a cryptographically secure random integer in [min, max].

func RandomString

func RandomString(length int, charset string) (string, error)

RandomString generates a cryptographically secure random string using the specified character set.

func RandomToken

func RandomToken(byteLength int) (string, error)

RandomToken generates a cryptographically secure random token. Uses URL-safe base64 encoding, suitable for API tokens, session IDs, etc. The byte length determines the entropy; the returned string will be longer.

func RandomUUID

func RandomUUID() (string, error)

RandomUUID generates a cryptographically secure random UUID (v4). Format: xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx where x is any hex digit and y is one of 8, 9, A, or B.

func SecureCompare

func SecureCompare(a, b string) bool

SecureCompare compares two strings and returns true if they are equal. This is an alias for ConstantTimeEqual for API compatibility.

func SetRandReader

func SetRandReader(r io.Reader)

SetRandReader sets the random reader (for testing purposes only). Pass nil to reset to the default crypto/rand.Reader.

func TimingSafeEqual

func TimingSafeEqual(a, b string) bool

TimingSafeEqual is another alias for ConstantTimeEqual. Named to match Python's hmac.compare_digest and Ruby's ActiveSupport::SecurityUtils.

func TruncateString

func TruncateString(s string, maxLen int) string

TruncateString truncates a string to the specified length. Adds "..." suffix if truncated.

func VerifyHMACSHA1 added in v1.1.0

func VerifyHMACSHA1(payload []byte, secret, signature string) bool

VerifyHMACSHA1 verifies an HMAC-SHA1 signature. Returns true if the signature is valid.

func VerifyHMACSHA256 added in v1.1.0

func VerifyHMACSHA256(payload []byte, secret, signature string) bool

VerifyHMACSHA256 verifies an HMAC-SHA256 signature. Returns true if the signature is valid.

func VerifyHMACSHA512 added in v1.1.0

func VerifyHMACSHA512(payload []byte, secret, signature string) bool

VerifyHMACSHA512 verifies an HMAC-SHA512 signature. Returns true if the signature is valid.

Types

type Argon2Hasher

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

Argon2Hasher implements the Hasher interface using Argon2id algorithm. Argon2id is the recommended variant as it provides both side-channel attack resistance (from Argon2i) and GPU attack resistance (from Argon2d).

func NewArgon2Hasher

func NewArgon2Hasher(opts ...Argon2Option) *Argon2Hasher

NewArgon2Hasher creates a new Argon2id hasher with default or custom parameters.

func (*Argon2Hasher) Algorithm

func (h *Argon2Hasher) Algorithm() string

Algorithm returns the name of the hash algorithm.

func (*Argon2Hasher) Check

func (h *Argon2Hasher) Check(hash, plaintext string) bool

Check implements the HashResolver interface.

func (*Argon2Hasher) Hash

func (h *Argon2Hasher) Hash(plaintext string) (string, error)

Hash generates an Argon2id hash from the given plaintext. The returned format is: "salt:hash" where both are base64-encoded. This format is compatible with Herald's existing implementation.

func (*Argon2Hasher) HashWithParams

func (h *Argon2Hasher) HashWithParams(plaintext string) (string, error)

HashWithParams generates an Argon2id hash and includes all parameters in the output. The returned format is: "$argon2id$v=19$m=65536,t=1,p=4$salt$hash" This format is compatible with other Argon2 implementations (PHC format).

func (*Argon2Hasher) Verify

func (h *Argon2Hasher) Verify(hash, plaintext string) bool

Verify checks if the plaintext matches the given hash. Supports both simple format (salt:hash) and PHC format ($argon2id$...).

type Argon2Option

type Argon2Option func(*Argon2Hasher)

Argon2Option is a function that configures an Argon2Hasher.

func WithArgon2KeyLen

func WithArgon2KeyLen(l uint32) Argon2Option

WithArgon2KeyLen sets the output key length in bytes.

func WithArgon2Memory

func WithArgon2Memory(m uint32) Argon2Option

WithArgon2Memory sets the memory usage in KB. Higher values increase memory-hardness and security.

func WithArgon2SaltLen

func WithArgon2SaltLen(l int) Argon2Option

WithArgon2SaltLen sets the salt length in bytes.

func WithArgon2Threads

func WithArgon2Threads(t uint8) Argon2Option

WithArgon2Threads sets the parallelism factor. Should not exceed the number of available CPU cores.

func WithArgon2Time

func WithArgon2Time(t uint32) Argon2Option

WithArgon2Time sets the number of iterations (time parameter). Higher values increase security but also computation time.

type BcryptHasher

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

BcryptHasher implements the Hasher interface using bcrypt algorithm. bcrypt is an industry-standard password hashing algorithm that automatically handles salt generation and includes the salt in the hash output.

func NewBcryptHasher

func NewBcryptHasher(opts ...BcryptOption) *BcryptHasher

NewBcryptHasher creates a new bcrypt hasher with default or custom parameters.

func (*BcryptHasher) Algorithm

func (h *BcryptHasher) Algorithm() string

Algorithm returns the name of the hash algorithm.

func (*BcryptHasher) Check

func (h *BcryptHasher) Check(hash, plaintext string) bool

Check implements the HashResolver interface. Compatible with existing Stargate implementations.

func (*BcryptHasher) Hash

func (h *BcryptHasher) Hash(plaintext string) (string, error)

Hash generates a bcrypt hash from the given plaintext. The returned hash includes the salt and cost factor.

func (*BcryptHasher) Verify

func (h *BcryptHasher) Verify(hash, plaintext string) bool

Verify checks if the plaintext matches the given hash. Returns true if the plaintext produces the same hash.

type BcryptOption

type BcryptOption func(*BcryptHasher)

BcryptOption is a function that configures a BcryptHasher.

func WithBcryptCost

func WithBcryptCost(cost int) BcryptOption

WithBcryptCost sets the bcrypt cost factor. Valid range is bcrypt.MinCost (4) to bcrypt.MaxCost (31). Higher values increase security but also computation time.

type BcryptResolver

type BcryptResolver struct{}

BcryptResolver is a zero-allocation implementation of HashResolver for bcrypt. This is a drop-in replacement for existing Stargate code.

func (*BcryptResolver) Check

func (b *BcryptResolver) Check(hash, plaintext string) bool

Check verifies if the plaintext matches the given bcrypt hash.

type HMACAlgorithm added in v1.1.0

type HMACAlgorithm int

HMACAlgorithm represents supported HMAC algorithms.

const (
	// HMACSHA1 uses SHA-1 for HMAC computation.
	// Note: SHA-1 is considered weak but still used by many webhook providers (e.g., GitHub).
	HMACSHA1 HMACAlgorithm = iota
	// HMACSHA256 uses SHA-256 for HMAC computation (recommended).
	HMACSHA256
	// HMACSHA512 uses SHA-512 for HMAC computation.
	HMACSHA512
)

func (HMACAlgorithm) Prefix added in v1.1.0

func (a HMACAlgorithm) Prefix() string

Prefix returns the common signature prefix (e.g., "sha256=").

func (HMACAlgorithm) String added in v1.1.0

func (a HMACAlgorithm) String() string

String returns the algorithm name.

type HMACVerifier added in v1.1.0

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

HMACVerifier provides HMAC signature generation and verification.

func NewHMACVerifier added in v1.1.0

func NewHMACVerifier(algorithm HMACAlgorithm, secret string) *HMACVerifier

NewHMACVerifier creates a new HMAC verifier with the specified algorithm and secret.

func NewHMACVerifierFromBytes added in v1.1.0

func NewHMACVerifierFromBytes(algorithm HMACAlgorithm, secret []byte) *HMACVerifier

NewHMACVerifierFromBytes creates a new HMAC verifier with a byte slice secret. This is useful when the secret is already decoded (e.g., from base64).

func (*HMACVerifier) Algorithm added in v1.1.0

func (v *HMACVerifier) Algorithm() HMACAlgorithm

Algorithm returns the HMAC algorithm being used.

func (*HMACVerifier) Sign added in v1.1.0

func (v *HMACVerifier) Sign(payload []byte) string

Sign computes the HMAC signature for the given payload. Returns the signature as a lowercase hex string.

func (*HMACVerifier) SignBase64 added in v1.1.0

func (v *HMACVerifier) SignBase64(payload []byte) string

SignBase64 computes the HMAC signature and returns it as base64. This is used by some providers like MS Teams.

func (*HMACVerifier) SignWithPrefix added in v1.1.0

func (v *HMACVerifier) SignWithPrefix(payload []byte) string

SignWithPrefix computes the HMAC signature and returns it with the algorithm prefix. Example: "sha256=abc123..."

func (*HMACVerifier) Verify added in v1.1.0

func (v *HMACVerifier) Verify(payload []byte, signature string) bool

Verify checks if the provided signature matches the computed HMAC. The signature can be with or without the algorithm prefix (e.g., "sha256=..."). Uses constant-time comparison to prevent timing attacks.

func (*HMACVerifier) VerifyAny added in v1.1.0

func (v *HMACVerifier) VerifyAny(payload []byte, signatures []string) (bool, string)

VerifyAny checks if any of the provided signatures match the computed HMAC. This is useful for webhooks that may send multiple signatures. Uses constant-time comparison to prevent timing attacks.

func (*HMACVerifier) VerifyBase64 added in v1.1.0

func (v *HMACVerifier) VerifyBase64(payload []byte, signature string) bool

VerifyBase64 checks if the provided base64-encoded signature matches. This is used by some providers like MS Teams.

type HashResolver

type HashResolver interface {
	// Check verifies if the plaintext matches the given hash.
	Check(hash, plaintext string) bool
}

HashResolver is a simplified interface for hash verification only. This is useful when you only need to verify hashes and don't need to generate new ones. Compatible with existing Stargate implementations.

type Hasher

type Hasher interface {
	// Hash generates a hash from the given plaintext.
	// Returns the hash string and any error encountered.
	// The returned hash format is algorithm-specific and includes any
	// necessary metadata (salt, parameters) for verification.
	Hash(plaintext string) (string, error)

	// Verify checks if the plaintext matches the given hash.
	// Returns true if the plaintext produces the same hash.
	// This method uses constant-time comparison to prevent timing attacks.
	Verify(hash, plaintext string) bool

	// Algorithm returns the name of the hash algorithm.
	Algorithm() string
}

Hasher defines a unified interface for hash operations. All hash implementations in this package implement this interface.

type MD5Hasher

type MD5Hasher struct{}

MD5Hasher implements the Hasher interface using MD5 algorithm.

WARNING: MD5 is cryptographically broken and should NOT be used for:

  • Password hashing
  • Security-critical applications
  • New implementations

This is provided ONLY for backward compatibility with legacy systems. For new implementations, use Argon2 or bcrypt instead.

func NewMD5Hasher

func NewMD5Hasher() *MD5Hasher

NewMD5Hasher creates a new MD5 hasher. Consider using NewArgon2Hasher or NewBcryptHasher for new implementations.

func (*MD5Hasher) Algorithm

func (h *MD5Hasher) Algorithm() string

Algorithm returns the name of the hash algorithm.

func (*MD5Hasher) Check

func (h *MD5Hasher) Check(hash, plaintext string) bool

Check implements the HashResolver interface.

func (*MD5Hasher) Hash

func (h *MD5Hasher) Hash(plaintext string) (string, error)

Hash generates an MD5 hash from the given plaintext. Returns the hash as a lowercase hex string.

func (*MD5Hasher) Verify

func (h *MD5Hasher) Verify(hash, plaintext string) bool

Verify checks if the plaintext matches the given hash. Comparison is case-insensitive for hex strings.

type MD5Resolver

type MD5Resolver struct{}

MD5Resolver is a zero-allocation implementation of HashResolver for MD5. This is a drop-in replacement for existing Stargate code.

WARNING: MD5 is cryptographically broken. Use only for legacy compatibility.

func (*MD5Resolver) Check

func (m *MD5Resolver) Check(hash, plaintext string) bool

Check verifies if the plaintext matches the given MD5 hash.

type PlaintextHasher

type PlaintextHasher struct{}

PlaintextHasher implements the Hasher interface for plaintext comparison.

WARNING: This does NOT actually hash anything. It is provided ONLY for:

  • Testing and development environments
  • Migration from legacy systems

NEVER use this in production for security-sensitive applications.

func NewPlaintextHasher

func NewPlaintextHasher() *PlaintextHasher

NewPlaintextHasher creates a new plaintext "hasher". Consider using NewArgon2Hasher or NewBcryptHasher for any real use case.

func (*PlaintextHasher) Algorithm

func (h *PlaintextHasher) Algorithm() string

Algorithm returns the name of the hash algorithm.

func (*PlaintextHasher) Check

func (h *PlaintextHasher) Check(hash, plaintext string) bool

Check implements the HashResolver interface.

func (*PlaintextHasher) Hash

func (h *PlaintextHasher) Hash(plaintext string) (string, error)

Hash returns the plaintext unchanged. This does NOT provide any security.

func (*PlaintextHasher) Verify

func (h *PlaintextHasher) Verify(hash, plaintext string) bool

Verify checks if the plaintext matches the given "hash". Uses constant-time comparison to prevent timing attacks.

type PlaintextResolver

type PlaintextResolver struct{}

PlaintextResolver is a zero-allocation implementation of HashResolver for plaintext. This is a drop-in replacement for existing Stargate code.

WARNING: This provides NO security. Use only for testing.

func (*PlaintextResolver) Check

func (p *PlaintextResolver) Check(hash, plaintext string) bool

Check verifies if the plaintext matches the given "hash".

type SHA256Hasher

type SHA256Hasher struct{}

SHA256Hasher implements the Hasher interface using SHA-256 algorithm. Note: SHA-256 is a fast hash and should NOT be used for password hashing. Use it for checksums, message authentication, or other non-password use cases.

func NewSHA256Hasher

func NewSHA256Hasher() *SHA256Hasher

NewSHA256Hasher creates a new SHA-256 hasher.

func (*SHA256Hasher) Algorithm

func (h *SHA256Hasher) Algorithm() string

Algorithm returns the name of the hash algorithm.

func (*SHA256Hasher) Check

func (h *SHA256Hasher) Check(hash, plaintext string) bool

Check implements the HashResolver interface.

func (*SHA256Hasher) Hash

func (h *SHA256Hasher) Hash(plaintext string) (string, error)

Hash generates a SHA-256 hash from the given plaintext. Returns the hash as a lowercase hex string.

func (*SHA256Hasher) Verify

func (h *SHA256Hasher) Verify(hash, plaintext string) bool

Verify checks if the plaintext matches the given hash. Comparison is case-insensitive for hex strings.

type SHA512Hasher

type SHA512Hasher struct{}

SHA512Hasher implements the Hasher interface using SHA-512 algorithm. Note: SHA-512 is a fast hash and should NOT be used for password hashing. Use it for checksums, message authentication, or other non-password use cases.

func NewSHA512Hasher

func NewSHA512Hasher() *SHA512Hasher

NewSHA512Hasher creates a new SHA-512 hasher.

func (*SHA512Hasher) Algorithm

func (h *SHA512Hasher) Algorithm() string

Algorithm returns the name of the hash algorithm.

func (*SHA512Hasher) Check

func (h *SHA512Hasher) Check(hash, plaintext string) bool

Check implements the HashResolver interface.

func (*SHA512Hasher) Hash

func (h *SHA512Hasher) Hash(plaintext string) (string, error)

Hash generates a SHA-512 hash from the given plaintext. Returns the hash as a lowercase hex string.

func (*SHA512Hasher) Verify

func (h *SHA512Hasher) Verify(hash, plaintext string) bool

Verify checks if the plaintext matches the given hash. Comparison is case-insensitive for hex strings.

type SHA512Resolver

type SHA512Resolver struct{}

SHA512Resolver is a zero-allocation implementation of HashResolver for SHA-512. This is a drop-in replacement for existing Stargate code.

func (*SHA512Resolver) Check

func (s *SHA512Resolver) Check(hash, plaintext string) bool

Check verifies if the plaintext matches the given SHA-512 hash.

Jump to

Keyboard shortcuts

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