{"record":{"id":"85b6b0831e70f33c","repo":"siyuan-note/siyuan","slug":"unsupported-encrypted-envelope-algorithm","errorCode":null,"errorMessage":"unsupported encrypted envelope algorithm","messagePattern":"unsupported encrypted envelope algorithm","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"kernel/util/kdf.go","lineNumber":113,"sourceCode":"\n// Decrypt 对应 Encrypt 的解密。密钥错误、格式无效或密文被篡改时返回错误。\nfunc Decrypt(key, ciphertext []byte) ([]byte, error) {\n\treturn decryptGCM(key, ciphertext, nil, \"Decrypt\")\n}\n\n// EncryptionNonce 从 AES-GCM 密文信封中提取 nonce。\nfunc EncryptionNonce(ciphertext []byte) ([]byte, error) {\n\tif !hasEncryptionMagic(ciphertext) {\n\t\treturn nil, errors.New(\"invalid encrypted envelope magic\")\n\t}\n\tif len(ciphertext) < encryptionEnvelopeHeaderSize {\n\t\treturn nil, errors.New(\"encrypted envelope too short\")\n\t}\n\tif ciphertext[len(encryptionMagic)] != EncryptionSpec {\n\t\treturn nil, errors.New(\"unsupported encrypted envelope spec\")\n\t}\n\tif ciphertext[len(encryptionMagic)+1] != encryptionAlgorithmAES256GCM {\n\t\treturn nil, errors.New(\"unsupported encrypted envelope algorithm\")\n\t}\n\tnonceLength := int(ciphertext[len(encryptionMagic)+2])\n\tif nonceLength == 0 || len(ciphertext) < encryptionEnvelopeHeaderSize+nonceLength {\n\t\treturn nil, errors.New(\"invalid encrypted envelope nonce length\")\n\t}\n\treturn append([]byte(nil), ciphertext[encryptionEnvelopeHeaderSize:encryptionEnvelopeHeaderSize+nonceLength]...), nil\n}\n\n// DeriveSubKey 用 HKDF-SHA256 从主 DEK 派生用途隔离的子密钥。\n// 同一 (dek, purpose) 多次调用结果一致；不同 purpose 派生出相互独立的子密钥，\n// 实现用途分离——.sy/assets/AV 各用独立子密钥，互不可替代，限制单点密钥泄漏的影响面。\nfunc DeriveSubKey(dek []byte, purpose string) []byte {\n\t// HKDF info 用 purpose 字节；salt 为 nil（DEK 本身已是高熵随机密钥，无需额外 salt）\n\tr := hkdf.New(sha256.New, dek, nil, []byte(purpose))\n\tout := make([]byte, 32) // AES-256\n\tif _, err := io.ReadFull(r, out); err != nil {\n\t\t// hkdf.Read 不应出错（除非 dek 为空）；防御性 panic 避免静默返回弱密钥\n\t\tpanic(\"hkdf derive failed: \" + err.Error())","sourceCodeStart":95,"sourceCodeEnd":131,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/9f775e8a12daef8255556097396f9b2739078892/kernel/util/kdf.go#L95-L131","documentation":"EncryptionNonce validates the envelope's algorithm byte (offset 5). Only AES-256-GCM (0x01) is implemented; any other algorithm identifier means the envelope was written with an unsupported cipher and cannot be processed.","triggerScenarios":"Calling EncryptionNonce on an envelope whose byte at offset 5 is not 0x01 — data written by a build supporting a different algorithm (e.g. ChaCha20-Poly1305 marker) or corrupted/tampered header bytes.","commonSituations":"Reading encrypted data produced by a different or newer kernel build, header corruption during storage/sync, or bit-flip tampering of the stored blob.","solutions":["Use the kernel version that wrote the envelope (matching algorithm support) to decrypt it","Restore the blob from backup if the header is corrupted (compare spec byte at offset 4 — if that is also wrong it is likely corruption)","Do not attempt to force-decrypt; GCM authentication would fail anyway with a wrong-key/wrong-algorithm combination"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"if len(data) >= 6 && data[5] != 0x01 {\n    return fmt.Errorf(\"envelope algorithm %d unsupported (AES-256-GCM=1 expected)\", data[5])\n}","typeGuard":"func isAESGCMEnvelope(b []byte) bool {\n    return len(b) >= 6 && string(b[:4]) == \"SENC\" && b[4] == 0x01 && b[5] == 0x01\n}","tryCatchPattern":"nonce, err := util.EncryptionNonce(ciphertext)\nif err != nil {\n    return fmt.Errorf(\"unsupported envelope algorithm: %w\", err)\n}","preventionTips":["Only read envelopes produced by the same kernel build family","Restore from backup if header bytes look corrupted (spec and algorithm both unexpected)","Never edit envelope header bytes by hand"],"tags":["encryption","aes-gcm","envelope-format","algorithm-support"],"backgroundTag":"unsupported-enum-value","analyzedSha":"9f775e8a12daef8255556097396f9b2739078892","analyzedAt":"2026-09-19T03:17:15.984Z","contentChangedAt":"2026-09-19T03:17:15.984Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}