siyuan-note/siyuan · error

unsupported encrypted envelope algorithm

Error message

unsupported encrypted envelope algorithm

What it means

Raised by EncryptionNonce when the algorithm byte at offset len(encryptionMagic)+1 (5) does not equal encryptionAlgorithmAES256GCM (1). Only AES-256-GCM is supported in the envelope today; any other algorithm byte is rejected.

Source

Thrown at kernel/util/kdf.go:113

// Decrypt 对应 Encrypt 的解密。密钥错误、格式无效或密文被篡改时返回错误。
func Decrypt(key, ciphertext []byte) ([]byte, error) {
	return decryptGCM(key, ciphertext, nil, "Decrypt")
}

// EncryptionNonce 从 AES-GCM 密文信封中提取 nonce。
func EncryptionNonce(ciphertext []byte) ([]byte, error) {
	if !hasEncryptionMagic(ciphertext) {
		return nil, errors.New("invalid encrypted envelope magic")
	}
	if len(ciphertext) < encryptionEnvelopeHeaderSize {
		return nil, errors.New("encrypted envelope too short")
	}
	if ciphertext[len(encryptionMagic)] != EncryptionSpec {
		return nil, errors.New("unsupported encrypted envelope spec")
	}
	if ciphertext[len(encryptionMagic)+1] != encryptionAlgorithmAES256GCM {
		return nil, errors.New("unsupported encrypted envelope algorithm")
	}
	nonceLength := int(ciphertext[len(encryptionMagic)+2])
	if nonceLength == 0 || len(ciphertext) < encryptionEnvelopeHeaderSize+nonceLength {
		return nil, errors.New("invalid encrypted envelope nonce length")
	}
	return append([]byte(nil), ciphertext[encryptionEnvelopeHeaderSize:encryptionEnvelopeHeaderSize+nonceLength]...), nil
}

// DeriveSubKey 用 HKDF-SHA256 从主 DEK 派生用途隔离的子密钥。
// 同一 (dek, purpose) 多次调用结果一致;不同 purpose 派生出相互独立的子密钥,
// 实现用途分离——.sy/assets/AV 各用独立子密钥,互不可替代,限制单点密钥泄漏的影响面。
func DeriveSubKey(dek []byte, purpose string) []byte {
	// HKDF info 用 purpose 字节;salt 为 nil(DEK 本身已是高熵随机密钥,无需额外 salt)
	r := hkdf.New(sha256.New, dek, nil, []byte(purpose))
	out := make([]byte, 32) // AES-256
	if _, err := io.ReadFull(r, out); err != nil {
		// hkdf.Read 不应出错(除非 dek 为空);防御性 panic 避免静默返回弱密钥
		panic("hkdf derive failed: " + err.Error())

View on GitHub (pinned to 251596fc0d)

Solutions

  1. Restore the blob from a known-good backup if corruption is suspected.
  2. Ensure you are running a kernel version compatible with the envelope's algorithm byte.
  3. Regenerate the ciphertext via Encrypt/EncryptWithAAD on a current build.
Defensive patterns

Strategy: validation

Validate before calling

if util.IsCiphertext(blob) && len(blob) > 5 && blob[5] != 1 { // encryptionAlgorithmAES256GCM
    return fmt.Errorf("envelope algorithm %d is unsupported", blob[5])
}

Prevention

When it happens

Trigger: EncryptionNonce reads a blob whose 6th byte is not 1. The byte was corrupted, or the blob came from a build that emitted a different algorithm identifier.

Common situations: Bit-rot in stored conf/asset ciphertext; a future envelope that adds a second algorithm but is read by a current kernel; an experimental build that wrote a different algorithm byte.

Related errors


AI-assisted analysis of siyuan-note/siyuan@251596fc0d (2026-08-12). Data as JSON: /api/errors/85b6b0831e70f33c. Report an issue: GitHub.