kdfcrypt

package module
v1.6.0 Latest Latest
Warning

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

Go to latest
Published: Aug 4, 2026 License: MIT Imports: 19 Imported by: 1

README

kdfcrypt

Go Reference Test

kdfcrypt is a Go library for deriving keys and encoding password hashes. It stores the algorithm, parameters, salt, and derived hash in one string, so multiple KDFs and parameter generations can coexist in the same application.

Supported algorithms are Argon2i, Argon2id, scrypt, PBKDF2, and HKDF. Use Argon2id for new password hashes. HKDF is intended for deriving keys from high-entropy key material, not for password storage.

The module requires Go 1.25 or later.

Password hashing

The algorithm must be selected explicitly. If neither Salt nor RandomSaltLength is set, Encode generates a 16-byte random salt.

package main

import (
	"fmt"
	"log"

	"github.com/xianghuzhao/kdfcrypt"
)

func main() {
	encoded, err := kdfcrypt.Encode("password", &kdfcrypt.Option{
		Algorithm: "argon2id",
	})
	if err != nil {
		log.Fatal(err)
	}

	match, err := kdfcrypt.Verify("password", encoded)
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(match) // true
}

Verify accepts hashes generated with older parameters because every encoded string contains its own parameters. Changing defaults only affects new calls that omit Option.Param; it does not strengthen existing stored hashes.

Defaults

Defaults apply only to fields omitted by the caller.

Algorithm Default parameters
Argon2id v=19,m=19456,t=2,p=1
Argon2i v=19,m=65536,t=1,p=1
scrypt N=131072,r=8,p=1
PBKDF2 iter=600000,hash=sha256
HKDF hash=sha512, empty info

The default derived hash length is 32 bytes. Password-hashing costs should be benchmarked on the deployment hardware and explicitly adjusted when needed. The defaults follow the baseline recommendations in the OWASP Password Storage Cheat Sheet.

Options

type Option struct {
	Algorithm        string // Required.
	Param            string // Comma-separated algorithm parameters.
	RandomSaltLength uint32 // Used when Salt is empty; zero defaults to 16.
	Salt             string // Explicit fixed salt; avoid for password storage.
	HashLength       uint32 // Zero defaults to 32.
}

An explicit non-empty Salt takes precedence over RandomSaltLength. The high-level Encode API never generates a new empty salt. Code that explicitly needs an empty salt can use EncodeFromKDF:

kdf, err := kdfcrypt.CreateKDF("pbkdf2", "iter=600000,hash=sha256")
if err != nil {
	return err
}
encoded, err := kdfcrypt.EncodeFromKDF("password", kdf, "", 32)

Fixed or empty salts should not be used for password storage.

Encoded format

Encoded passwords use Raw standard Base64 and exactly four $-separated fields:

$argon2id$v=19,m=19456,t=2,p=1$c2FsdA$aGFzaA
$ algorithm $ parameters              $ salt $ hash

Parsing is strict. Duplicate, unknown, missing, overflowing, or malformed parameters are rejected. Verify is designed for encoded values loaded from trusted application storage. It does not impose resource limits on valid KDF cost parameters, so applications must not let an attacker supply an arbitrary encoded string directly.

Malformed encodings, invalid parameters, and unavailable algorithms can be classified with errors.Is and ErrInvalidEncoding, ErrInvalidParameter, or ErrUnsupportedAlgorithm. A valid encoding with the wrong password returns false, nil.

Deriving encryption keys

For a 32-byte AES-256 key, preserve the KDF algorithm, parameters, and salt so the same key can be derived again:

kdf, err := kdfcrypt.CreateKDF("argon2id", "m=19456,t=2,p=1")
if err != nil {
	return err
}
salt, err := kdfcrypt.GenerateRandomSalt(16)
if err != nil {
	return err
}
key, err := kdf.Derive([]byte("password"), salt, 32)

HKDF can be used when the input is already high-entropy key material:

kdf, err := kdfcrypt.CreateKDF("hkdf", "hash=sha512,info=example-context")
if err != nil {
	return err
}
key, err := kdf.Derive(masterSecret, salt, 32)

Algorithm parameters

  • Argon2i and Argon2id: m is memory in KiB, t is the number of passes, p is parallelism, and v is the Argon2 version.
  • scrypt: N is the CPU/memory cost and must be a power of two greater than one, r is the block size, and p is parallelism.
  • PBKDF2: iter is the iteration count and hash is the HMAC hash function.
  • HKDF: hash is the HMAC hash function and info is optional context.

Supported PBKDF2 and HKDF hash names are md5, sha1, sha224, sha256, sha384, sha512, sha512/224, and sha512/256.

Documentation

Index

Constants

This section is empty.

Variables

View Source
var (
	// ErrInvalidEncoding indicates that an encoded password is malformed.
	ErrInvalidEncoding = errors.New("invalid password encoding")
	// ErrInvalidParameter indicates that an option or KDF parameter is invalid.
	ErrInvalidParameter = errors.New("invalid KDF parameter")
	// ErrUnsupportedAlgorithm indicates that a KDF algorithm is not registered.
	ErrUnsupportedAlgorithm = errors.New("unsupported KDF algorithm")
)

Functions

func Encode added in v1.0.0

func Encode(password string, opt *Option) (string, error)

Encode generates an encoded password hash.

func EncodeFromKDF added in v1.0.0

func EncodeFromKDF(password string, kdf KDF, salt string, hashLength uint32) (string, error)

EncodeFromKDF encodes a password with the given KDF and salt.

func GenerateRandomSalt added in v1.0.0

func GenerateRandomSalt(saltLength uint32) ([]byte, error)

GenerateRandomSalt generates random salt.

func KDFName added in v1.0.0

func KDFName(kdf KDF) (string, error)

KDFName returns the algorithm name of the KDF.

func ListKDFAlgorithms added in v1.1.0

func ListKDFAlgorithms() []string

ListKDFAlgorithms lists all registered KDF algorithms in sorted order.

func RegisterKDF added in v1.0.0

func RegisterKDF(algorithm string, kdf KDF)

RegisterKDF registers a KDF type with an algorithm name.

func Verify

func Verify(password, encoded string) (bool, error)

Verify reports whether password matches an encoded password hash.

Types

type Argon2 added in v1.0.0

type Argon2 struct {
	Version     uint8  `param:"v"`
	Memory      uint32 `param:"m"`
	Iteration   uint32 `param:"t"`
	Parallelism uint8  `param:"p"`
}

Argon2 contains parameters shared by Argon2 variants.

func (*Argon2) SetDefaultParam added in v1.0.0

func (kdf *Argon2) SetDefaultParam()

SetDefaultParam sets the default parameters for Argon2i.

type Argon2i added in v1.0.0

type Argon2i struct {
	Argon2
}

Argon2i implements the Argon2i KDF.

func (*Argon2i) Derive added in v1.5.0

func (kdf *Argon2i) Derive(password, salt []byte, hashLength uint32) ([]byte, error)

Derive derives a key with Argon2i.

type Argon2id

type Argon2id struct {
	Argon2
}

Argon2id implements the Argon2id KDF.

func (*Argon2id) Derive added in v1.5.0

func (kdf *Argon2id) Derive(password, salt []byte, hashLength uint32) ([]byte, error)

Derive derives a key with Argon2id.

func (*Argon2id) SetDefaultParam added in v1.6.0

func (kdf *Argon2id) SetDefaultParam()

SetDefaultParam sets the default parameters for Argon2id.

type HKDF added in v1.0.0

type HKDF struct {
	HashFunc string `param:"hash"`
	Info     string `param:"info"`
}

HKDF contains HKDF parameters.

func (*HKDF) Derive added in v1.5.0

func (kdf *HKDF) Derive(password, salt []byte, hashLength uint32) ([]byte, error)

Derive derives a key with HKDF.

func (*HKDF) SetDefaultParam added in v1.0.0

func (kdf *HKDF) SetDefaultParam()

SetDefaultParam sets the default HKDF parameters.

type KDF

type KDF interface {
	SetDefaultParam()
	Derive(password, salt []byte, hashLength uint32) ([]byte, error)
}

KDF is implemented by key derivation functions registered with this package.

func CreateKDF

func CreateKDF(algorithm, param string) (KDF, error)

CreateKDF creates a key derivation function.

type Option added in v1.0.0

type Option struct {
	Algorithm        string
	Param            string
	RandomSaltLength uint32
	Salt             string
	HashLength       uint32
}

Option configures Encode.

type PBKDF2

type PBKDF2 struct {
	Iteration uint32 `param:"iter"`
	HashFunc  string `param:"hash"`
}

PBKDF2 contains PBKDF2 parameters.

func (*PBKDF2) Derive added in v1.5.0

func (kdf *PBKDF2) Derive(password, salt []byte, hashLength uint32) ([]byte, error)

Derive derives a key with PBKDF2.

func (*PBKDF2) SetDefaultParam added in v1.0.0

func (kdf *PBKDF2) SetDefaultParam()

SetDefaultParam sets the default PBKDF2 parameters.

type Scrypt added in v1.0.0

type Scrypt struct {
	Cost            int `param:"N"`
	BlockSize       int `param:"r"`
	Parallelization int `param:"p"`
}

Scrypt contains scrypt parameters.

func (*Scrypt) Derive added in v1.5.0

func (kdf *Scrypt) Derive(password, salt []byte, hashLength uint32) ([]byte, error)

Derive derives a key with scrypt.

func (*Scrypt) SetDefaultParam added in v1.0.0

func (kdf *Scrypt) SetDefaultParam()

SetDefaultParam sets the default scrypt parameters.

Jump to

Keyboard shortcuts

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