Skip to main content
Version: Next

password Package

import "github.com/croessner/nauthilus/v3/pluginapi/v1/password"

This package works with credentials. Avoid the string/byte convenience functions when a request-scoped pluginapi.Secret is available; they make secret lifetime and copying harder to control.

Public errors

var ErrUnsupportedAlgorithm = errors.New("unsupported hash algorithm")
var ErrUnsupportedEncoding = errors.New("unsupported password encoding")

ErrUnsupportedAlgorithm covers salted-SHA algorithms/prefixes outside the public contract and malformed salted-SHA inputs that cannot supply a valid salt. ErrUnsupportedEncoding covers non-base64/non-hex salted-SHA encoding choices. Decode and external crypt errors can also be returned; use errors.Is only for the two sentinels.

Algorithm

type Algorithm uint8
ConstantNumeric valueMeaning
AlgorithmUnknown0Unsupported/unparsed algorithm.
AlgorithmSSHA2561Salted SHA-256.
AlgorithmSSHA5122Salted SHA-512.

Only SSHA-256 and SSHA-512 are accepted by CryptPassword.Generate....

Encoding

type Encoding uint8
ConstantNumeric valueMeaning
EncodingUnknown0Unsupported/unparsed encoding.
EncodingBase641Standard base64 of digest concatenated with salt.
EncodingHex2Lowercase hexadecimal of digest concatenated with salt.

CryptPassword

type CryptPassword struct {
Salt []byte
Password string
Algorithm Algorithm
Encoding Encoding
}
FieldMeaning
SaltCopied salt bytes parsed or used for generation. Secret-sensitive.
PasswordEncoded `digest
AlgorithmParsed/generated algorithm.
EncodingParsed/generated payload encoding.

The object is mutable and not documented as concurrency-safe. Zero values represent no parsed/generated password.

(*CryptPassword).GenerateString

func (c *CryptPassword) GenerateString(
plainPassword string,
salt []byte,
algorithm Algorithm,
encoding Encoding,
) (string, error)

Converts the plaintext string to bytes and delegates to GenerateBytes. Prefer the byte or Secret paths to avoid immutable plaintext strings.

(*CryptPassword).GenerateBytes

func (c *CryptPassword) GenerateBytes(
plainPassword []byte,
salt []byte,
algorithm Algorithm,
encoding Encoding,
) (string, error)

Computes SHA-256(password || salt) or SHA-512(password || salt), appends the salt to the digest, encodes the combined bytes, copies the salt into the receiver, and sets all fields. It returns only the encoded payload. To store a full hash, the caller must add one of the matching SSHA-family prefixes shown below: SSHA256 uses default base64 and SSHA512.HEX selects SHA-512 plus hex. Unknown algorithms/encodings return the public sentinels. Empty salt is accepted for generation, but such output cannot later pass GetParameters because the parser requires payload bytes beyond the fixed digest length.

(*CryptPassword).GetParameters

func (c *CryptPassword) GetParameters(
cryptedPassword string,
) (salt []byte, algorithm Algorithm, encoding Encoding, err error)

Accepts the exact case-sensitive form:

{SSHA256}<payload>
{SSHA256.B64}<payload>
{SSHA256.HEX}<payload>
{SSHA512}<payload>
{SSHA512.B64}<payload>
{SSHA512.HEX}<payload>

An omitted suffix defaults to base64. It decodes the payload, requires at least one salt byte after the 32- or 64-byte digest, stores the payload/metadata and a copied salt, and returns a separate salt copy. Prefix/shape/short-payload failures use ErrUnsupportedAlgorithm; payload decode errors are returned directly.

Password comparison

CompareHash

func CompareHash(hashPassword string, plainPassword pluginapi.Secret) (bool, error)

Returns false, nil for a nil secret. Otherwise it borrows bytes through Secret.WithBytes and delegates to CompareHashBytes. A callback/secret error is returned. The final encoded comparison is constant-time.

CompareHashString

func CompareHashString(hashPassword, plainPassword string) (bool, error)

Converts plaintext to bytes and delegates. It is a convenience API; the plaintext string cannot be cleared.

CompareHashBytes

func CompareHashBytes(hashPassword string, plainPassword []byte) (bool, error)

Hashes whose prefix begins with an opening brace followed by SSHA use the salted-SHA parser/generator above. Other hashes are decoded and verified through the package's github.com/simia-tech/crypt dependency using the settings embedded in the stored hash. Unsupported/malformed formats or dependency errors are returned. It compares the full recomputed encoded hash with the stored hash using subtle.ConstantTimeCompare.

The function does not clear caller-owned plaintext bytes. The caller owns their lifetime.

HashOptions

type HashOptions struct {
Nonce []byte
DevMode bool
}

Nonce is prepended before a NUL separator. It is not copied by the struct. DevMode changes the result from a short digest to raw prepared credential material and is dangerous outside tightly controlled development.

Short-hash functions

GenerateHash

func GenerateHash(secret pluginapi.Secret, options HashOptions) (string, error)

Returns "", nil for a nil secret. Otherwise it borrows secret bytes, calls GenerateHashBytes, and returns any Secret.WithBytes error.

GenerateHashString

func GenerateHashString(password string, options HashOptions) string

String convenience wrapper around GenerateHashBytes.

GenerateHashBytes

func GenerateHashBytes(password []byte, options HashOptions) string

Builds the prepared byte sequence, defers clear on that temporary slice, and calls ShortHash. It cannot clear caller-owned password/nonce inputs or the returned string.

PrepareBytes

func PrepareBytes(password, nonce []byte) []byte

Allocates and returns:

nonce || 0x00 || password

The separator is present even for an empty nonce. Caller owns and should clear the returned slice after use.

ShortHash

func ShortHash(value []byte, devMode bool) string

When devMode is false, returns the first eight lowercase hexadecimal characters of SHA-256 over value (32 bits, suitable only as a short correlation value, not password storage or authorization). When true, it returns string(value) unchanged.

Development-mode credential exposure

With the normal prepared input, development mode returns nonce || NUL || plaintext password as a Go string. The host uses the same helper for PostActionRequest.PasswordHash, which is delivered to all post-action targets regardless of credentials capability. Always treat that field as a credential and never log, trace, persist, or expose it.