golang/go · error

crypto/pbkdf2: use of salts shorter than 128 bits is not all

Error message

crypto/pbkdf2: use of salts shorter than 128 bits is not allowed in FIPS 140-only mode

What it means

Returned by pbkdf2.Key in FIPS 140-only mode when the salt is shorter than 16 bytes (128 bits). SP 800-132 mandates salts of at least 128 bits for approved PBKDF2 use; the Go module enforces this. The check triggers only when fips140only.Enforced() is true.

Source

Thrown at src/crypto/pbkdf2/pbkdf2.go:47

//
//	dk, err := pbkdf2.Key(sha1.New, "some password", salt, 4096, 32)
//
// Remember to get a good random salt. At least 8 bytes is recommended by the
// RFC.
//
// Using a higher iteration count will increase the cost of an exhaustive
// search but will also make derivation proportionally slower.
//
// keyLength must be a positive integer between 1 and (2^32 - 1) * h.Size().
// Setting keyLength to a value outside of this range will result in an error.
func Key[Hash hash.Hash](h func() Hash, password string, salt []byte, iter, keyLength int) ([]byte, error) {
	fh := fips140hash.UnwrapNew(h)
	if fips140only.Enforced() {
		if keyLength < 112/8 {
			return nil, errors.New("crypto/pbkdf2: use of keys shorter than 112 bits is not allowed in FIPS 140-only mode")
		}
		if len(salt) < 128/8 {
			return nil, errors.New("crypto/pbkdf2: use of salts shorter than 128 bits is not allowed in FIPS 140-only mode")
		}
		if !fips140only.ApprovedHash(fh()) {
			return nil, errors.New("crypto/pbkdf2: use of hash functions other than SHA-2 or SHA-3 is not allowed in FIPS 140-only mode")
		}
	}
	return pbkdf2.Key(fh, password, salt, iter, keyLength)
}

View on GitHub (pinned to b6b368adc5)

Solutions

  1. Generate at least 16 bytes of salt: salt := make([]byte, 16); crypto/rand.Read(salt).
  2. Use a longer salt (32 bytes) for stronger defense and future margin.
  3. If bound to a legacy short salt, run outside FIPS-only mode with documented rationale.

Example fix

// before
salt := []byte("salt") // 4 bytes
dk, err := pbkdf2.Key(sha256.New, pass, salt, iter, 32) // FIPS error

// after
salt := make([]byte, 16)
rand.Read(salt)
dk, err := pbkdf2.Key(sha256.New, pass, salt, iter, 32)
Defensive patterns

Strategy: validation

Validate before calling

const minSaltLen = 16 // 128 bits
if fips140only.Enforced() && len(salt) < minSaltLen {
    salt = make([]byte, 16)
    crypto/rand.Read(salt)
}
return pbkdf2.Key(sha256.New, pass, salt, iter, keyLength)

Type guard

func isFipsSafeSalt(s []byte) bool { return len(s) >= 16 }

Try / catch

dk, err := pbkdf2.Key(h, pass, salt, iter, keyLength)
if err != nil && strings.Contains(err.Error(), "salts shorter than 128 bits") {
    salt = make([]byte, 16)
    crypto/rand.Read(salt)
    dk, err = pbkdf2.Key(h, pass, salt, iter, keyLength)
}
return dk, err

Prevention

When it happens

Trigger: Calling pbkdf2.Key with a salt of fewer than 16 bytes in a FIPS-only build. Reusing a short hardcoded salt from a pre-FIPS design.

Common situations: Legacy apps with a fixed short salt migrated into FIPS mode. Generating salt from a weak source that yields < 16 bytes. Test fixtures with minimal salts.

Related errors


AI-assisted analysis of golang/go@b6b368adc5 (2026-08-12). Data as JSON: /api/errors/d281b2898e827e55. Report an issue: GitHub.