{"record":{"id":"5c79639a22a39629","repo":"siyuan-note/siyuan","slug":"argon2id-keylength-must-be-32","errorCode":null,"errorMessage":"Argon2id KeyLength must be 32","messagePattern":"Argon2id KeyLength must be 32","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"kernel/util/kdf.go","lineNumber":65,"sourceCode":"\tParallelism uint8  `json:\"parallelism\"` // 并行线程数\n\tKeyLength   uint32 `json:\"keyLength\"`   // 输出密钥长度，单位字节\n}\n\n// DefaultArgon2Params 返回 OWASP 2023 推荐的 Argon2id 参数。\nfunc DefaultArgon2Params() Argon2Params {\n\treturn Argon2Params{\n\t\tMemory:      64 * 1024,\n\t\tIterations:  3,\n\t\tParallelism: 4,\n\t\tKeyLength:   32,\n\t}\n}\n\n// ValidateArgon2Params 校验 Argon2id 参数是否在合理范围内，防止恶意备份设置极大内存导致 OOM，\n// 或过弱参数降低安全性。\nfunc ValidateArgon2Params(p Argon2Params) (Argon2Params, error) {\n\tif p.KeyLength != 32 {\n\t\treturn p, errors.New(\"Argon2id KeyLength must be 32\")\n\t}\n\tif p.Memory < 64*1024 {\n\t\treturn p, errors.New(\"Argon2id Memory too low (minimum 64 MB)\")\n\t}\n\tif p.Memory > 256*1024 {\n\t\treturn p, errors.New(\"Argon2id Memory too high (maximum 256 MB)\")\n\t}\n\tif p.Iterations < 3 {\n\t\treturn p, errors.New(\"Argon2id Iterations too low (minimum 3)\")\n\t}\n\tif p.Iterations > 10 {\n\t\treturn p, errors.New(\"Argon2id Iterations too high (maximum 10)\")\n\t}\n\tif p.Parallelism == 0 || p.Parallelism > 16 {\n\t\treturn p, errors.New(\"Argon2id Parallelism must be between 1 and 16\")\n\t}\n\treturn p, nil\n}","sourceCodeStart":47,"sourceCodeEnd":83,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/251596fc0de2f9528c00c224252fd073a99973f4/kernel/util/kdf.go#L47-L83","documentation":"Raised by ValidateArgon2Params when p.KeyLength != 32. SiYuan's AES-256-GCM envelope (Encrypt/Decrypt and the wrapped-DEK scheme) requires a 32-byte derived key, so any other KeyLength is rejected to prevent a downstream 'requires a 32-byte (AES-256) key' failure or, worse, a silently truncated key.","triggerScenarios":"A notebook crypto config (KDFParams) is loaded from a backup or hand-edited JSON with keyLength set to something other than 32; ValidateArgon2Params is called during unlock/setup/change-password (crypto.go, crypto_lifecycle.go) and returns this error before any key derivation.","commonSituations":"Restoring a backup whose JSON was edited and keyLength was changed; a third-party tool writing notebook crypto metadata with a wrong field; a corrupted conf where the field defaulted to 0.","solutions":["Reset KDFParams.KeyLength to 32 in the notebook crypto config (DefaultArgon2Params already sets it).","If the config is from an external/modified backup, regenerate crypto params via the official change-password flow rather than editing JSON.","Validate the struct with ValidateArgon2Params immediately after deserializing, so the bad value is caught at load time."],"exampleFix":"// before\nparams := util.Argon2Params{Memory: 64 * 1024, Iterations: 3, Parallelism: 4, KeyLength: 16}\n\n// after: AES-256 requires a 32-byte key\nparams := util.DefaultArgon2Params() // KeyLength: 32","handlingStrategy":"validation","validationCode":"params := util.DefaultArgon2Params() // guarantees KeyLength == 32\nif _, err := util.ValidateArgon2Params(params); err != nil {\n    return err\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always source KDFParams from DefaultArgon2Params or the official change-password flow.","Run ValidateArgon2Params right after deserializing notebook crypto config to fail fast.","Never hand-edit keyLength in conf JSON."],"tags":["crypto","argon2","encryption","validation","notebook-crypto"],"backgroundTag":null,"analyzedSha":"251596fc0de2f9528c00c224252fd073a99973f4","analyzedAt":"2026-08-12T21:18:37.123Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}