{"record":{"id":"c89bd9082f552550","repo":"gofiber/fiber","slug":"decode-sha256-password-invalid-length","errorCode":null,"errorMessage":"decode SHA256 password: invalid length","messagePattern":"decode SHA256 password: invalid length","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"middleware/basicauth/config.go","lineNumber":21,"sourceCode":"import (\n\t\"crypto/sha256\"\n\t\"crypto/sha512\"\n\t\"crypto/subtle\"\n\t\"encoding/base64\"\n\t\"encoding/hex\"\n\t\"errors\"\n\t\"fmt\"\n\t\"sort\"\n\t\"strconv\"\n\t\"strings\"\n\n\t\"github.com/gofiber/fiber/v3\"\n\t\"github.com/gofiber/utils/v2\"\n\t\"golang.org/x/crypto/bcrypt\"\n)\n\nvar (\n\tErrInvalidSHA256PasswordLength = errors.New(\"decode SHA256 password: invalid length\")\n\tErrInvalidSHA512PasswordLength = errors.New(\"decode SHA512 password: invalid length\")\n)\n\n// fallbackDummySHA512 is SHA-512(\"fiber-basicauth-dummy\"), used as a\n// constant-time comparison target when no users are configured.\nvar fallbackDummySHA512 = [sha512.Size]byte{\n\t0x85, 0xc7, 0xd4, 0xbc, 0xec, 0x5f, 0xdf, 0xef, 0xe0, 0x4d, 0xd4, 0x3e, 0xd3, 0xac, 0x45, 0x7c,\n\t0x5e, 0x48, 0x60, 0x74, 0x12, 0x8e, 0xf8, 0xc0, 0xde, 0x39, 0x89, 0xf9, 0x84, 0x0c, 0x50, 0x24,\n\t0x1e, 0xa6, 0x1f, 0x2a, 0x11, 0x97, 0xb1, 0xb9, 0x67, 0xa9, 0xf7, 0x3b, 0x82, 0x8f, 0x95, 0xf5,\n\t0x58, 0xed, 0x3c, 0xab, 0x43, 0x22, 0xf6, 0xfa, 0x84, 0x1d, 0xbc, 0xeb, 0x87, 0xc4, 0x1c, 0x5a,\n}\n\ntype passwordVerifier func(string) bool\n\ntype userVerifiers map[string]passwordVerifier\n\n// Verifier strengths are ordered by expected verification work:\n// bcrypt is strongest because it is adaptive and cost-based, SHA-512 follows","sourceCodeStart":3,"sourceCodeEnd":39,"githubUrl":"https://github.com/gofiber/fiber/blob/a105acad6c1e4576a77f01e02973f67e962bb58d/middleware/basicauth/config.go#L3-L39","documentation":"Returned by middleware/basicauth when a configured password hash is decoded from base64/hex but the resulting bytes are not exactly sha256.Size (32) long. basicauth accepts \"{SHA256}\"-prefixed base64, bare hex, or bare base64 SHA-256 digests; any of them must decode to a 32-byte digest or comparison can never match. The length check rejects truncated/corrupted hashes at config time instead of silently failing every login.","triggerScenarios":"Configuring a user with a \"{SHA256}<b64>\" value whose payload is not 32 bytes, a bare hash string that base64-decodes to the wrong length, or a hex digest that was copy-truncated.","commonSituations":"Copying a SHA-256 hash from a tool that emitted the hex form but pasting it under the \"{SHA256}\" base64 convention (or vice versa); truncating the digest in a config file; migrating from SHA-512 hashes without changing the prefix.","solutions":["Regenerate the hash as a 32-byte SHA-256 digest and base64-encode it for the \"{SHA256}\" form.","If using hex, ensure the full 64-character hex string is present (no truncation).","Use the matching prefix: \"{SHA256}\" for base64, \"{SHA512}\" for 64-byte digests.","Verify length programmatically at startup with a config validator."],"exampleFix":"// before\nUsers: map[string]string{\n  \"alice\": \"{SHA256}\" + hexdigest, // hex under a base64 prefix\n}\n// after\nimport \"crypto/sha256\",\"encoding/base64\"\nsum := sha256.Sum256([]byte(\"password\"))\nUsers: map[string]string{\n  \"alice\": \"{SHA256}\" + base64.StdEncoding.EncodeToString(sum[:]),\n}","handlingStrategy":"validation","validationCode":"func validSHA256(h string) error {\n    s := strings.TrimPrefix(h, \"{SHA256}\")\n    b, err := base64.StdEncoding.DecodeString(s)\n    if err != nil {\n        b, err = hex.DecodeString(s)\n        if err != nil { return err }\n    }\n    if len(b) != sha256.Size {\n        return basicauth.ErrInvalidSHA256PasswordLength\n    }\n    return nil\n}","typeGuard":null,"tryCatchPattern":"fn, err := basicauth.ValidateUserCreds(...)\nif err != nil {\n    if errors.Is(err, basicauth.ErrInvalidSHA256PasswordLength) {\n        // reject the user config at startup; do not serve with a broken hash\n    }\n}","preventionTips":["Generate hashes with a checked helper: base64(sha256(password)) and prefix with {SHA256}.","Validate every configured hash at startup before listening.","Keep hex vs base64 conventions consistent within a single config."],"tags":["basicauth","auth","config","crypto"],"backgroundTag":null,"analyzedSha":"a105acad6c1e4576a77f01e02973f67e962bb58d","analyzedAt":"2026-08-11T17:33:26.942Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}