{"id":"6bb342649d1f142b","repo":"gofiber/fiber","slug":"failed-to-create-aes-cipher-w","errorCode":null,"errorMessage":"failed to create AES cipher: %w","messagePattern":"failed to create AES cipher: %w","errorType":"http","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"middleware/encryptcookie/utils.go","lineNumber":49,"sourceCode":"\treturn keyDecoded, nil\n}\n\n// validateKey checks if the provided base64-encoded key is of valid length.\nfunc validateKey(key string) error {\n\t_, err := decodeKey(key)\n\treturn err\n}\n\n// EncryptCookie Encrypts a cookie value with specific encryption key\nfunc EncryptCookie(name, value, key string) (string, error) {\n\tkeyDecoded, err := decodeKey(key)\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\n\tblock, err := aes.NewCipher(keyDecoded)\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"failed to create AES cipher: %w\", err)\n\t}\n\n\tgcm, err := cipher.NewGCMWithRandomNonce(block)\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"failed to create GCM mode: %w\", err)\n\t}\n\n\tciphertext := gcm.Seal(nil, nil, []byte(value), []byte(name))\n\treturn base64.StdEncoding.EncodeToString(ciphertext), nil\n}\n\n// DecryptCookie Decrypts a cookie value with specific encryption key\nfunc DecryptCookie(name, value, key string) (string, error) {\n\tkeyDecoded, err := decodeKey(key)\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n","sourceCodeStart":31,"sourceCodeEnd":67,"githubUrl":"https://github.com/gofiber/fiber/blob/9a4c7e57fe0b080a04235d28a4b0d2b4b353d58c/middleware/encryptcookie/utils.go#L31-L67","documentation":"Thrown at middleware/encryptcookie/utils.go:49 inside EncryptCookie() when aes.NewCipher(keyDecoded) returns an error. In the normal public flow this is effectively unreachable: decodeKey() already ran first and validated the decoded length is exactly 16, 24, or 32 bytes - the only condition aes.NewCipher rejects. The check exists as a defensive guard; seeing it means the key length validation was bypassed (e.g. calling decodeKey-equivalent logic partially) or a future Go crypto/aes change.","triggerScenarios":"Only fires if aes.NewCipher is handed a key whose length is not 16/24/32. Via EncryptCookie/DecryptCookie that cannot happen because decodeKey enforces those lengths first. Realistically seen only in custom forks that skip the validation, or in tests calling aes.NewCipher directly with a malformed key.","commonSituations":"Custom Decryptor/Encryptor override that re-implements the key handling without the length check; an internal refactor that reorders decodeKey and aes.NewCipher; AES-NI unavailable on an exotic platform returning an unexpected error (very unlikely).","solutions":["If you wrote a custom Encryptor/Decryptor, replicate the decodeKey length validation (16/24/32) BEFORE calling aes.NewCipher.","Audit any code path that constructs an AES cipher to confirm key length is enforced upstream.","Run encryptcookie.ValidateKey(key) at startup; if it passes, error 158 cannot fire later via the public API.","On exotic platforms, confirm crypto/aes is functional with a smoke test (aes.NewCipher(make([]byte, 16)))."],"exampleFix":"// before: custom decryptor skips length validation\ncfg.Decryptor = func(name, value, key string) (string, error) {\n    raw, _ := base64.StdEncoding.DecodeString(key) // skip length check\n    block, err := aes.NewCipher(raw)               // can fail -> error 158\n    ...\n}\n\n// after: reuse decodeKey for validation, then construct the cipher\nraw, err := decodeKey(key) // validates base64 + 16/24/32 length\nif err != nil { return \"\", err }\nblock, err := aes.NewCipher(raw) // safe; length already enforced\nif err != nil {\n    return \"\", fmt.Errorf(\"failed to create AES cipher: %w\", err)\n}","handlingStrategy":"validation","validationCode":"// At startup, confirm the key produces a working AES cipher.\nif err := encryptcookie.ValidateKey(key); err != nil {\n    log.Fatalf(\"invalid cookie key: %v\", err)\n}\n// Optional: round-trip a sample to exercise the AES path.\nif _, err := encryptcookie.EncryptCookie(\"probe\", \"x\", key); err != nil {\n    log.Fatalf(\"AES cipher construction failed: %v\", err)\n}","typeGuard":"// Ensure any custom encryptor enforces AES key lengths before constructing the cipher.\nfunc isAESKeyLen(raw []byte) bool {\n    switch len(raw) {\n    case 16, 24, 32: return true\n    }\n    return false\n}","tryCatchPattern":"// In a custom encryptor, never skip the length check that decodeKey provides.\nraw, err := decodeKey(key) // validates base64 + 16/24/32 length\nif err != nil { return \"\", err }\nblock, err := aes.NewCipher(raw)\nif err != nil {\n    return \"\", fmt.Errorf(\"failed to create AES cipher: %w\", err)\n}","preventionTips":["Reuse encryptcookie.decodeKey in custom encryptors rather than re-implementing key handling.","Run a round-trip smoke test (encrypt then decrypt) at startup.","Keep key-length validation upstream of any aes.NewCipher call.","On exotic platforms, smoke-test crypto/aes availability before serving traffic."],"tags":["encryptcookie","crypto","aes","fiber"],"analyzedSha":"9a4c7e57fe0b080a04235d28a4b0d2b4b353d58c","analyzedAt":"2026-08-04T21:44:03.395Z","schemaVersion":2}