This document covers password hashing algorithms (Argon2, bcrypt, scrypt, PBKDF2) and cryptographic hash functions (BLAKE2, SHA-3) provided by golang.org/x/crypto.
Argon2 is the winner of the Password Hashing Competition. It provides two variants: Argon2i (optimized for password hashing) and Argon2id (hybrid mode recommended for most use cases).
const Version = 0x13 // Argon2 version 1.3// IDKey derives a key from the password, salt and cost parameters using Argon2id.
// Argon2id is the recommended variant that is resistant to both side-channel and GPU attacks.
func IDKey(password, salt []byte, time, memory uint32, threads uint8, keyLen uint32) []byte
// Key derives a key from the password, salt and cost parameters using Argon2i.
// Argon2i is optimized for password hashing but less resistant to GPU attacks than Argon2id.
func Key(password, salt []byte, time, memory uint32, threads uint8, keyLen uint32) []bytepassword: The password to hashsalt: A unique salt (16 bytes recommended)time: Number of iterations (3+ recommended)memory: Memory in KiB (64MB = 65536 recommended)threads: Degree of parallelism (typically 4)keyLen: Desired key length in bytes (32 recommended)package main
import (
"crypto/rand"
"fmt"
"golang.org/x/crypto/argon2"
)
func main() {
password := []byte("my-secure-password")
salt := make([]byte, 16)
rand.Read(salt)
// Recommended parameters for Argon2id
hash := argon2.IDKey(password, salt, 3, 64*1024, 4, 32)
fmt.Printf("Hash: %x\n", hash)
// Store both salt and hash for verification
}bcrypt is an adaptive hash function based on the Blowfish cipher, designed for password hashing with automatic cost adjustment.
const (
MinCost int = 4 // Minimum allowable cost
MaxCost int = 31 // Maximum allowable cost
DefaultCost int = 10 // Default cost (recommended minimum)
)var ErrHashTooShort = errors.New("crypto/bcrypt: hashedSecret too short to be a bcrypted password")
var ErrMismatchedHashAndPassword = errors.New("crypto/bcrypt: hashedPassword is not the hash of the given password")
var ErrPasswordTooLong = errors.New("bcrypt: password length exceeds 72 bytes")// GenerateFromPassword returns the bcrypt hash of the password at the given cost.
// If the cost given is less than MinCost, the cost will be set to DefaultCost.
func GenerateFromPassword(password []byte, cost int) ([]byte, error)
// CompareHashAndPassword compares a bcrypt hashed password with its possible plaintext equivalent.
// Returns nil on success, or an error on failure.
func CompareHashAndPassword(hashedPassword, password []byte) error
// Cost returns the hashing cost used to create the given hashed password.
func Cost(hashedPassword []byte) (int, error)// HashVersionTooNewError is returned when the hash version is newer than this implementation supports.
type HashVersionTooNewError byte
func (hv HashVersionTooNewError) Error() string
// InvalidCostError is returned when the cost is out of range.
type InvalidCostError int
func (ic InvalidCostError) Error() string
// InvalidHashPrefixError is returned when the hash prefix is invalid.
type InvalidHashPrefixError byte
func (ih InvalidHashPrefixError) Error() stringpackage main
import (
"fmt"
"golang.org/x/crypto/bcrypt"
)
func main() {
password := []byte("my-secure-password")
// Hash password
hash, err := bcrypt.GenerateFromPassword(password, bcrypt.DefaultCost)
if err != nil {
panic(err)
}
fmt.Printf("Hash: %s\n", hash)
// Verify password
err = bcrypt.CompareHashAndPassword(hash, password)
if err == nil {
fmt.Println("Password is correct!")
}
// Check cost
cost, _ := bcrypt.Cost(hash)
fmt.Printf("Cost used: %d\n", cost)
}scrypt is a password-based key derivation function designed to be expensive in both CPU and memory, making it resistant to hardware attacks.
// Key derives a key from the password, salt and cost parameters using scrypt.
// N is the CPU/memory cost parameter (power of 2, e.g., 32768)
// r is the block size parameter (e.g., 8)
// p is the parallelization parameter (e.g., 1)
// keyLen is the length of the derived key
func Key(password, salt []byte, N, r, p, keyLen int) ([]byte, error)N: CPU/memory cost (must be power of 2, e.g., 32768)r: Block size (e.g., 8)p: Parallelization (e.g., 1)package main
import (
"crypto/rand"
"fmt"
"golang.org/x/crypto/scrypt"
)
func main() {
password := []byte("my-secure-password")
salt := make([]byte, 32)
rand.Read(salt)
// Recommended parameters for interactive logins
hash, err := scrypt.Key(password, salt, 32768, 8, 1, 32)
if err != nil {
panic(err)
}
fmt.Printf("Hash: %x\n", hash)
}PBKDF2 (Password-Based Key Derivation Function 2) is defined in RFC 2898 and PKCS #5 v2.0.
// Key derives a key from the password, salt and iteration count using PBKDF2.
// The iter parameter specifies the iteration count (10000+ recommended).
// h is a hash function constructor (e.g., sha256.New).
func Key(password, salt []byte, iter, keyLen int, h func() hash.Hash) []bytepackage main
import (
"crypto/rand"
"crypto/sha256"
"fmt"
"golang.org/x/crypto/pbkdf2"
)
func main() {
password := []byte("my-secure-password")
salt := make([]byte, 16)
rand.Read(salt)
// Use PBKDF2 with SHA-256 and 100,000 iterations
hash := pbkdf2.Key(password, salt, 100000, 32, sha256.New)
fmt.Printf("Hash: %x\n", hash)
}HKDF (HMAC-based Extract-and-Expand Key Derivation Function) is defined in RFC 5869 and is used for deriving keys from shared secrets.
// New returns a reader from which keys can be derived using the HKDF key derivation function.
// hash is the hash function (e.g., sha256.New).
// secret is the input keying material.
// salt is a non-secret random value (optional, can be nil).
// info is application-specific context and application (optional).
func New(hash func() hash.Hash, secret, salt, info []byte) io.Reader
// Extract performs the extract step of HKDF.
// It returns a pseudorandom key derived from the secret and salt.
func Extract(hash func() hash.Hash, secret, salt []byte) []byte
// Expand performs the expand step of HKDF.
// It expands a pseudorandom key into multiple keys.
func Expand(hash func() hash.Hash, pseudorandomKey, info []byte) io.Readerpackage main
import (
"crypto/sha256"
"fmt"
"io"
"golang.org/x/crypto/hkdf"
)
func main() {
secret := []byte("shared-secret")
salt := []byte("unique-salt")
info := []byte("application-context")
// Derive keys
kdf := hkdf.New(sha256.New, secret, salt, info)
// Read derived key material
key := make([]byte, 32)
io.ReadFull(kdf, key)
fmt.Printf("Derived key: %x\n", key)
}BLAKE2b is a cryptographic hash function defined in RFC 7693. It's faster than MD5, SHA-1, SHA-2, and SHA-3, yet is at least as secure as SHA-3.
const (
BlockSize = 128 // Block size in bytes
Size = 64 // Hash size in bytes for BLAKE2b-512
Size384 = 48 // Hash size in bytes for BLAKE2b-384
Size256 = 32 // Hash size in bytes for BLAKE2b-256
)
const OutputLengthUnknown = 0// New returns a new hash.Hash computing the BLAKE2b checksum with a custom length.
// size is the hash length (1 to 64 bytes).
// key is an optional MAC key (up to 64 bytes, can be nil).
func New(size int, key []byte) (hash.Hash, error)
// New256 returns a new hash.Hash computing the BLAKE2b-256 checksum.
func New256(key []byte) (hash.Hash, error)
// New384 returns a new hash.Hash computing the BLAKE2b-384 checksum.
func New384(key []byte) (hash.Hash, error)
// New512 returns a new hash.Hash computing the BLAKE2b-512 checksum.
func New512(key []byte) (hash.Hash, error)
// Sum256 returns the BLAKE2b-256 checksum of the data.
func Sum256(data []byte) [Size256]byte
// Sum384 returns the BLAKE2b-384 checksum of the data.
func Sum384(data []byte) [Size384]byte
// Sum512 returns the BLAKE2b-512 checksum of the data.
func Sum512(data []byte) [Size]byte// XOF is an interface for variable-output-length hash functions.
type XOF interface {
io.Writer
io.Reader
Clone() XOF
Reset()
}
// NewXOF creates a new variable-output-length hash using BLAKE2Xb.
// size is the output length in bytes (0 for unlimited).
func NewXOF(size uint32, key []byte) (XOF, error)package main
import (
"fmt"
"golang.org/x/crypto/blake2b"
)
func main() {
data := []byte("hello world")
// Simple hash
hash256 := blake2b.Sum256(data)
fmt.Printf("BLAKE2b-256: %x\n", hash256)
hash512 := blake2b.Sum512(data)
fmt.Printf("BLAKE2b-512: %x\n", hash512)
// Keyed hash (MAC)
key := []byte("secret-key")
h, _ := blake2b.New256(key)
h.Write(data)
mac := h.Sum(nil)
fmt.Printf("BLAKE2b-256 MAC: %x\n", mac)
// Variable output length
xof, _ := blake2b.NewXOF(64, nil)
xof.Write(data)
out := make([]byte, 64)
xof.Read(out)
fmt.Printf("BLAKE2Xb: %x\n", out)
}BLAKE2s is a variant of BLAKE2 optimized for 8- to 32-bit platforms.
const (
BlockSize = 64 // Block size in bytes
Size = 32 // Hash size in bytes for BLAKE2s-256
Size128 = 16 // Hash size in bytes for BLAKE2s-128
)
const OutputLengthUnknown = 0// New128 returns a new hash.Hash computing the BLAKE2s-128 checksum.
// Note: BLAKE2s-128 should only be used as a MAC, not for general hashing.
func New128(key []byte) (hash.Hash, error)
// New256 returns a new hash.Hash computing the BLAKE2s-256 checksum.
func New256(key []byte) (hash.Hash, error)
// Sum256 returns the BLAKE2s-256 checksum of the data.
func Sum256(data []byte) [Size]byte// XOF is an interface for variable-output-length hash functions.
type XOF interface {
io.Writer
io.Reader
Clone() XOF
Reset()
}
// NewXOF creates a new variable-output-length hash using BLAKE2Xs.
// size is the output length in bytes (0 for unlimited).
func NewXOF(size uint16, key []byte) (XOF, error)SHA-3 (Secure Hash Algorithm 3) is the latest member of the Secure Hash Algorithm family, defined in FIPS 202.
// New224 returns a new SHA3-224 hash.Hash.
func New224() hash.Hash
// New256 returns a new SHA3-256 hash.Hash.
func New256() hash.Hash
// New384 returns a new SHA3-384 hash.Hash.
func New384() hash.Hash
// New512 returns a new SHA3-512 hash.Hash.
func New512() hash.Hash
// Sum224 returns the SHA3-224 digest of the data.
func Sum224(data []byte) [28]byte
// Sum256 returns the SHA3-256 digest of the data.
func Sum256(data []byte) [32]byte
// Sum384 returns the SHA3-384 digest of the data.
func Sum384(data []byte) [48]byte
// Sum512 returns the SHA3-512 digest of the data.
func Sum512(data []byte) [64]byte
// NewLegacyKeccak256 returns a new Keccak-256 hash (pre-FIPS 202).
// This is the hash used by Ethereum. Only use for compatibility.
func NewLegacyKeccak256() hash.Hash
// NewLegacyKeccak512 returns a new Keccak-512 hash (pre-FIPS 202).
// Only use for compatibility with legacy systems.
func NewLegacyKeccak512() hash.Hash
// ShakeSum128 writes an arbitrary-length digest of data to hash.
func ShakeSum128(hash, data []byte)
// ShakeSum256 writes an arbitrary-length digest of data to hash.
func ShakeSum256(hash, data []byte)// ShakeHash is an interface for SHAKE hash functions.
type ShakeHash interface {
hash.Hash
io.Reader
Clone() ShakeHash
}
// NewShake128 returns a new SHAKE128 variable-output-length ShakeHash.
func NewShake128() ShakeHash
// NewShake256 returns a new SHAKE256 variable-output-length ShakeHash.
func NewShake256() ShakeHash
// NewCShake128 returns a new cSHAKE128 customizable ShakeHash.
// N is the function name, S is the customization string.
func NewCShake128(N, S []byte) ShakeHash
// NewCShake256 returns a new cSHAKE256 customizable ShakeHash.
// N is the function name, S is the customization string.
func NewCShake256(N, S []byte) ShakeHashpackage main
import (
"fmt"
"golang.org/x/crypto/sha3"
)
func main() {
data := []byte("hello world")
// Fixed-length SHA-3
hash256 := sha3.Sum256(data)
fmt.Printf("SHA3-256: %x\n", hash256)
hash512 := sha3.Sum512(data)
fmt.Printf("SHA3-512: %x\n", hash512)
// Variable-length SHAKE
shake := sha3.NewShake256()
shake.Write(data)
out := make([]byte, 64)
shake.Read(out)
fmt.Printf("SHAKE256: %x\n", out)
// Customizable cSHAKE
cshake := sha3.NewCShake256([]byte("MyApp"), []byte("v1.0"))
cshake.Write(data)
out2 := make([]byte, 32)
cshake.Read(out2)
fmt.Printf("cSHAKE256: %x\n", out2)
}MD4 hash algorithm (RFC 1320). Deprecated - use SHA-256 instead.
const BlockSize = 64
const Size = 16// New returns a new hash.Hash computing the MD4 checksum.
// Deprecated: MD4 is cryptographically broken and should not be used for secure applications.
func New() hash.HashRIPEMD-160 hash algorithm. Deprecated - use SHA-256 instead.
const BlockSize = 64
const Size = 20// New returns a new hash.Hash computing the RIPEMD-160 checksum.
// Deprecated: RIPEMD-160 is a legacy hash function and should not be used for new applications.
func New() hash.Hash