func (PBKDF2) Validate(hashed, plain string) (bool, error) {
	parts := strings.Split(hashed, "$")
	if len(parts) != 5 {
		return false, errInvalidPBKDF2
	}
	alg := parts[1]
	algorithm, err := ParseAlgorithm(alg)
	if err != nil {
		return false, err
	}
	iter, err := strconv.ParseInt(parts[2], 10, 32)
	if err != nil {
		return false, errIterations.WithAttributes("iterations", parts[2])
	}
	salt := parts[3]
	key := parts[4]
	keylen, err := keyLen(key)
	if err != nil {
		return false, errKeyLength.WithCause(err)
	}
	hash := hash64([]byte(plain), []byte(salt), int(iter), keylen, algorithm)
	return subtle.ConstantTimeCompare(hash, []byte(key)) == 1, nil
}
Validate validates a plaintext password against a hashed one.
The format of the hashed password should be:

PBKDF2$<algorithm>$<iterations>$<salt>$<key in base64>
package pbkdf2
import (
	"crypto/subtle"
	"encoding/base64"
	"fmt"
	"strconv"
	"strings"
	"go.thethings.network/lorawan-stack/v3/pkg/errors"
	"go.thethings.network/lorawan-stack/v3/pkg/random"
	"golang.org/x/crypto/pbkdf2"
)
var defaultInstance = PBKDF2{
	Iterations: 20000,
	KeyLength:  32,
	Algorithm:  Sha256,
	SaltLength: 16,
}
func Default() PBKDF2 { return defaultInstance }
type PBKDF2 struct {
	Iterations int
	Algorithm Algorithm
	SaltLength int
	KeyLength int
}
func (PBKDF2) Name() string {
	return "PBKDF2"
}
var errZeroLengthSalt = errors.DefineInternal(
	"zero_length_salt",
	"password salt can not have zero length",
)
func (p PBKDF2) Hash(plain string) (string, error) {
	if p.SaltLength == 0 {
		return "", errZeroLengthSalt.New()
	}
	salt := random.String(p.SaltLength)
	hash := hash64([]byte(plain), []byte(salt), p.Iterations, p.KeyLength, p.Algorithm)
	pass := fmt.Sprintf("%s$%s$%v$%s$%s", p.Name(), p.Algorithm, p.Iterations, salt, string(hash))
	return pass, nil
}
var errInvalidPBKDF2 = errors.DefineInternal(  
	"invalid_pbkdf2_format",
	"password hash has invalid PBKDF2 format",
)
var errIterations = errors.DefineInternal(
	"pbkdf2_iterations",
	"could not determine number of iterations from `{iterations}`",
)
var errKeyLength = errors.DefineInternal(
	"pbkdf2_key_length",
	"could not determine key length",
)