{"record":{"id":"ad1373379b3cb251","repo":"siyuan-note/siyuan","slug":"decryption-failed-incorrect-key-or-corrupted-data-ad1373","errorCode":null,"errorMessage":"Decryption failed: incorrect key or corrupted data [box=%s]","messagePattern":"Decryption failed: incorrect key or corrupted data \\[box=(.+?)\\]","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"kernel/model/crypto.go","lineNumber":1733,"sourceCode":"\t}\n\tnewKEK := util.DeriveKey(newPassword, nc.MasterSalt, params)\n\tdefer zeroAndClear(newKEK)\n\tnewVerifier, err := util.EncryptWithAAD(newKEK, kekVerifierMagic, []byte(\"siyuan:kek-verifier\"))\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t// Phase 0: 遍历所有加密笔记本（含 conf 损坏但存在备份的），预计算新 WrappedDEK（内存操作）\n\t// 允许 entries 为空：用户可能已启用加密功能但尚未创建加密笔记本，此时仍需更新全局 verifier 和 backup。\n\tencBoxIDs, listErr := listAllEncryptedBoxIDs()\n\tif listErr != nil {\n\t\treturn fmt.Errorf(\"list encrypted notebooks failed: %w\", listErr)\n\t}\n\tvar entries []migrationBoxEntry\n\tfor _, id := range encBoxIDs {\n\t\tdek, boxCrypt, dErr := decryptBoxCrypt(id, oldKEK)\n\t\tif dErr != nil {\n\t\t\treturn errors.New(Conf.Language(316) + \" [box=\" + id + \"]\")\n\t\t}\n\t\tnewWrapped, nErr := util.EncryptWithAAD(newKEK, dek, wrappedDEKAAD(id))\n\t\tif nErr != nil {\n\t\t\treturn nErr\n\t\t}\n\t\tentries = append(entries, migrationBoxEntry{\n\t\t\tBoxID:         id,\n\t\t\tNewSpec:       boxEncryptionSpec,\n\t\t\tNewWrappedDEK: newWrapped,\n\t\t\tNewWrapNonce:  mustEncryptionNonce(newWrapped),\n\t\t\tMetadata:      append([]byte(nil), boxCrypt.Metadata...),\n\t\t})\n\t}\n\n\t// Phase 1: 持久化 migration manifest（崩溃后 recovery 的依据）\n\tnewParamsJSON, _ := gulu.JSON.MarshalJSON(params)\n\tmig := &masterPasswordMigration{\n\t\tOldVerifier:      nc.KEKVerifier,","sourceCodeStart":1715,"sourceCodeEnd":1751,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/afa823b6b4e4f183511e0bc0a3be93caa94c7c97/kernel/model/crypto.go#L1715-L1751","documentation":"Returned by ChangeMasterPassword Phase 0 (crypto.go:1730-1733) when decryptBoxCrypt fails to unwrap a notebook's DEK with the KEK derived from oldPassword - both the conf.json WrappedDEK and the backup fallback reject it (message 316 plus a [box=ID] suffix naming the offender). It means the old password is wrong, or that specific notebook's key material is from a different KEK generation or corrupted.","triggerScenarios":"Wrong oldPassword typed into the change-password dialog (most common); a leftover notebook whose WrappedDEK was already re-wrapped by an interrupted earlier migration; one notebook's conf+backup key material corrupted while the global verifier still authenticates.","commonSituations":"User confuses old and new password fields; a previous change attempt crashed after Phase 2 leaving mixed generations; selective corruption of one notebook's conf.json.","solutions":["Re-enter the current (old) master password and retry","If a password change was interrupted before, restart SiYuan and let migration recovery complete before attempting another change","Identify the box from the [box=ID] suffix, inspect/restore that notebook's conf.json and crypt backup from a snapshot, then retry"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"if err := model.ChangeMasterPassword(oldPw, newPw); err != nil {\n    if strings.Contains(err.Error(), Conf.Language(316)) {\n        // message carries [box=ID]; wrong old password or that box's key material is stale\n        if boxID := extractBoxIDSuffix(err); boxID != \"\" {\n            inspectBoxKeyMaterial(boxID) // restore conf+backup from snapshot if damaged\n        } else {\n            promptForCorrectOldPassword()\n        }\n    }\n}","preventionTips":["Confirm the old password unlocks an encrypted notebook (or passes the settings verifier) before starting the change","If a previous change attempt was interrupted, restart and let migration recovery finish first","Keep consistent snapshots of every encrypted notebook's conf and crypt backup"],"tags":["encryption","aes-gcm","master-password","argon2"],"backgroundTag":"aes-gcm-decryption-failed","analyzedSha":"afa823b6b4e4f183511e0bc0a3be93caa94c7c97","analyzedAt":"2026-08-18T17:04:10.865Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}