encryption

package
v1.2.6 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 29, 2026 License: AGPL-3.0 Imports: 9 Imported by: 0

Documentation

Overview

Package encryption SQLCipher-style page-level transparent encryption. AES-256-CBC per-page encryption + HMAC-SHA256 integrity verification. Inserted at the Pager layer, invisible to upper SQL/BTree/MVCC layers.

Package encryption - 加密头(存储于页 0 MetaPage 之后的预留空间)

Package encryption - 密钥派生函数(PBKDF2-SHA256)

Index

Constants

View Source
const EncryptionHeaderMagic uint32 = 0x56445345

EncryptionHeaderMagic 加密数据库标识 "VDSE"(VDS Encrypted)

View Source
const EncryptionHeaderOffset = 49

EncryptionHeaderOffset 加密头在页 0 中的偏移(MetaPage 49 字节之后)

View Source
const EncryptionHeaderSize = 112

EncryptionHeaderSize 加密头序列化大小

View Source
const HMACSize = 16

HMACSize per-page integrity tag size (16 bytes)

View Source
const HeaderVersion = 3

HeaderVersion 加密头格式版本。 版本 1:确定性 IV(deriveIV(pageID)),页格式 = pageSize + HMACSize,零 IV 验证块 版本 2:非确定性 IV(nonce XOR deriveIV(pageID)),页格式 = NonceSize + pageSize + HMACSize,零 IV 验证块 版本 3:与版本 2 相同,验证块使用随机 nonce(nonce XOR deriveIV(0))

View Source
const KeySize = 32

KeySize AES-256 key size

View Source
const NonceSize = 8

NonceSize per-page random nonce size, stored as prefix of encrypted page. Used to derive a non-deterministic IV so identical plaintext pages produce different ciphertext.

View Source
const PBKDF2Iterations = 600000

PBKDF2Iterations 密钥派生迭代次数。 M3 修复:64000 → 600000,对齐 OWASP 2023 推荐值。 注意:升级后旧数据库的密钥派生使用新迭代数不影响解密(salt+passphrase 相同即可), 仅影响新建数据库或密钥重派生场景。

Variables

View Source
var ErrHMACMismatch = errors.New("encryption: HMAC mismatch")
View Source
var ErrKeyInvalid = errors.New("encryption: invalid key")

Functions

func DeriveKeys

func DeriveKeys(passphrase string, salt []byte) (encKey, macKey []byte, err error)

DeriveKeys 从 passphrase + salt 派生 encKey 和 macKey。

派生链:

masterKey = PBKDF2-SHA256(passphrase, salt, 64000, 32)
encKey    = HMAC-SHA256(masterKey, "vds-encryption-key")[0:32]
macKey    = HMAC-SHA256(masterKey, "vds-mac-key")[0:32]

两个独立 key 保证加密和完整性校验的密钥隔离, 即使 encKey 泄露也无法伪造 HMAC tag。

func DeriveKeysFromRaw

func DeriveKeysFromRaw(rawKey []byte) (encKey, macKey []byte, err error)

DeriveKeysFromRaw 从原始 32 字节密钥派生 encKey 和 macKey。 用于开发者直接提供 AES-256 原始密钥(跳过 PBKDF2)。

func GenerateSalt

func GenerateSalt() ([]byte, error)

GenerateSalt generates a 32-byte random salt for PBKDF2.

func IsEncrypted

func IsEncrypted(page0 []byte) bool

IsEncrypted 判断字节切片是否包含有效的加密头。

Types

type EncryptionHeader

type EncryptionHeader struct {
	Magic             uint32   // 0x56445345
	Version           uint32   // 1
	Salt              [32]byte // PBKDF2 随机盐
	VerificationBlock [64]byte // 验证块密文(16 字节有效 + 48 字节 padding)
}

EncryptionHeader 页 0 中的加密元数据(明文存储,用于密钥验证)。

布局(112 字节):

Offset  Size  字段
0       4     Magic: 0x56445345 ("VDSE")
4       4     Version
8       32    Salt (PBKDF2)
40      64    验证块密文(AES-256-CBC("VDS-KEY-VERIFY\x00"),恰好 1 个 block)
104     8     保留

func NewEncryptionHeader

func NewEncryptionHeader(salt, verifyCiphertext []byte) (*EncryptionHeader, error)

NewEncryptionHeader 创建加密头。 salt 是 PBKDF2 随机盐,verifyCiphertext 是加密后的验证块。

func ReadEncryptionHeader

func ReadEncryptionHeader(page0 []byte) (*EncryptionHeader, error)

ReadEncryptionHeader 从页 0 数据中读取加密头。

func (*EncryptionHeader) WriteTo

func (h *EncryptionHeader) WriteTo(page0 []byte)

WriteTo 将加密头写入页 0 数据缓冲区(从 EncryptionHeaderOffset 开始)。

type EncryptionType

type EncryptionType uint8

EncryptionType encryption algorithm type

const (
	EncryptionNone   EncryptionType = 0
	EncryptionAES256 EncryptionType = 1
)

type PageCipher

type PageCipher struct {
	// contains filtered or unexported fields
}

PageCipher holds encKey and macKey for page-level encryption. Thread-safe: instance is immutable after construction.

func NewPageCipher

func NewPageCipher(encKey, macKey []byte) (*PageCipher, error)

func (*PageCipher) Clear added in v1.2.1

func (pc *PageCipher) Clear()

Clear 安全擦除内存中的密钥材料,防止密钥在堆内存中残留。 调用后 PageCipher 实例不可再用于加解密操作。

func (*PageCipher) DecryptBlob

func (pc *PageCipher) DecryptBlob(ciphertext []byte, id uint32) ([]byte, error)

DecryptBlob decrypts variable-length data and removes PKCS7 padding.

func (*PageCipher) DecryptPage

func (pc *PageCipher) DecryptPage(data []byte, pageID uint32) ([]byte, error)

DecryptPage decrypts a page (including HMAC tag), handling both old and new formats.

Detection strategy:

  1. Try new format: extract nonce from data[:NonceSize], verify HMAC over data[NonceSize:len(data)-HMACSize], use nonce-XOR'd IV.
  2. If HMAC fails, fall back to old format: HMAC over data[:len(data)-HMACSize], use pageID-only deterministic IV.

Returns plaintext (exactly pageSize bytes).

func (*PageCipher) DecryptVerificationBlock

func (pc *PageCipher) DecryptVerificationBlock(data []byte) ([]byte, error)

DecryptVerificationBlock decrypts the verification block. M3 修复:自动检测格式。

  • 旧格式(16 字节):零 IV AES-CBC 解密(版本 1/2 数据库)
  • 新格式(24 字节):nonce(8B) || ciphertext(16B)(版本 3 数据库)

func (*PageCipher) EncryptBlob

func (pc *PageCipher) EncryptBlob(plaintext []byte, id uint32) ([]byte, error)

EncryptBlob encrypts variable-length data with PKCS7 padding.

func (*PageCipher) EncryptPage

func (pc *PageCipher) EncryptPage(plaintext []byte, pageID uint32) ([]byte, error)

EncryptPage encrypts a page of plaintext using AES-256-CBC with a random nonce. Format (new): nonce(8B) || ciphertext(pageSize) || HMAC(16B) The nonce is XOR'd into the first 8 bytes of deriveIV(pageID) to produce a non-deterministic per-encryption IV. Identical plaintext pages no longer produce identical ciphertext.

HMAC is computed over ciphertext only (not the nonce prefix), matching the old format's HMAC range for backward compatibility.

func (*PageCipher) EncryptVerificationBlock

func (pc *PageCipher) EncryptVerificationBlock() ([]byte, error)

EncryptVerificationBlock encrypts the 16-byte verification block. M3 修复:使用随机 nonce 替代零 IV,防止已知明文攻击削弱密钥暴力破解抗性。 格式: nonce(8B) || ciphertext(16B),nonce XOR'd into deriveIV(0)。

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL