a2

package
v1.1.1 Latest Latest
Warning

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

Go to latest
Published: Oct 11, 2025 License: MIT Imports: 15 Imported by: 0

README

A2 版本 - 高性能并行加密

📋 概述

A2 版本是 A1 的升级版,主要改进:

  • AES-CBC 替换为 AES-GCM 加密模式
  • 默认使用多核并行加密/解密,显著提升性能
  • 修复 GCM nonce 重用安全问题
  • 提供 AEAD 认证加密,防止数据篡改
  • 简化代码结构,优化性能

🔐 加密方案

核心技术
  • RSA 4096位: 用于加密 AES 密钥和配置
  • AES-256-GCM: 用于加密实际数据 (AEAD 认证加密)
  • 多核并行: 充分利用多核 CPU 性能
  • tar.xz: 用于数据压缩
加密流程
原始文件/目录
    ↓
tar 打包
    ↓
xz 压缩
    ↓
分块 (64KB 块)
    ↓
并行 AES-GCM 加密
    ↓
添加文件头
    ↓
加密压缩包

📦 加密文件结构

完整结构布局
┌────────────────────────────────────────────────────┐
│ 版本头 (2 字节)                                      │
│ ┌──────────┬──────────┐                            │
│ │ Protocol │ Version  │                            │
│ │   'A'    │    2     │                            │
│ │ (1 byte) │ (1 byte) │                            │
│ └──────────┴──────────┘                            │
├────────────────────────────────────────────────────┤
│ 文件头 (14 字节)                                     │
│ ┌──────────────┬────────────────────────────┐      │
│ │ IsEncryption │        Padding             │      │
│ │   (bool)     │      (13 bytes)            │      │
│ │  (1 byte)    │                            │      │
│ └──────────────┴────────────────────────────┘      │
├────────────────────────────────────────────────────┤
│ [如果加密] RSA 加密的 AES 配置 (512 字节)              │
│                                                    │
│ RSA-4096 加密的二进制数据:                          │
│ ┌──────────────────────────────────────┐           │
│ │ Nonce  (12 bytes) - GCM 基础 nonce   │           │
│ │ Key    (32 bytes) - AES-256 密钥     │           │
│ │ Salt   (16 bytes) - 盐值             │           │
│ └──────────────────────────────────────┘           │
│ 总共 60 字节,RSA 加密后固定 512 字节               │
│                                                    │
│ 使用公钥加密,私钥解密                               │
├────────────────────────────────────────────────────┤
│ [如果加密] AES-GCM 加密数据块序列                     │
│                                                    │
│ ┌────────────────────────────────────────┐         │
│ │ 数据块 0:                               │         │
│ │  ┌──────────────┐                      │         │
│ │  │ 块长度       │ uint32, 4 bytes      │         │
│ │  ├──────────────┤                      │         │
│ │  │ 密文 + 标签  │ N bytes + 16 bytes   │         │
│ │  └──────────────┘                      │         │
│ ├────────────────────────────────────────┤         │
│ │ 数据块 1:                               │         │
│ │  ┌──────────────┐                      │         │
│ │  │ 块长度       │ uint32, 4 bytes      │         │
│ │  ├──────────────┤                      │         │
│ │  │ 密文 + 标签  │ N bytes + 16 bytes   │         │
│ │  └──────────────┘                      │         │
│ ├────────────────────────────────────────┤         │
│ │           ... 更多数据块 ...           │         │
│ ├────────────────────────────────────────┤         │
│ │ 最后一块:                               │         │
│ │  ┌──────────────┐                      │         │
│ │  │ 块长度       │ uint32, 4 bytes      │         │
│ │  ├──────────────┤                      │         │
│ │  │ 密文 + 标签  │ M bytes + 16 bytes   │         │
│ │  └──────────────┘                      │         │
│ └────────────────────────────────────────┘         │
│                                                    │
│ 每个块使用唯一的 nonce (基础nonce XOR 块索引)       │
│ 支持多核并行加密/解密                               │
├────────────────────────────────────────────────────┤
│ tar.xz 压缩数据                                     │
│                                                    │
│ 原始数据经过 tar 打包 + xz 压缩后的结果              │
└────────────────────────────────────────────────────┘
详细字段说明
1. 版本头 (2 字节)
字段 类型 大小 说明
Protocol byte 1 'A' (0x41) 协议标识符
Version uint8 1 2 版本号

编码方式: Big Endian 二进制

2. 文件头 (14 字节)
字段 类型 大小 说明
IsEncryption bool 1 是否加密 (true=加密, false=未加密)
Padding byte[] 13 填充字节(保留用于未来扩展)

编码方式: Big Endian 二进制

3. RSA 加密块 (512 字节,仅加密时存在)

大小: 固定 512 字节 (RSA-4096 密文长度)

内容: 使用 RSA 公钥加密的二进制格式 AES 配置

解密后的二进制结构 (60 字节):

字段 类型 大小 说明
Nonce [12]byte 12 GCM 基础 nonce
Key [32]byte 32 AES-256 密钥
Salt [16]byte 16 盐值(保留)

编码方式: Big Endian 二进制

RSA 加密参数:

  • 算法: RSA PKCS#1 v1.5
  • 密钥长度: 4096 位
  • 明文长度: 60 字节
  • 密文固定长度: 512 字节

兼容性说明: A2 也能解密旧版本使用 JSON 格式的配置块。

4. AES-GCM 加密数据块 (仅加密时存在)

加密参数:

  • 算法: AES-256-GCM
  • 密钥长度: 256 位 (32 字节)
  • Nonce 长度: 96 位 (12 字节)
  • 认证标签: 128 位 (16 字节)
  • 默认块大小: 64 KB

数据块格式:

每个数据块包含两部分:

  1. 块长度 (4 字节):

    • 类型: uint32
    • 编码: Big Endian
    • 值: 密文长度(包含 16 字节认证标签)
    • 范围: 17 - 65552 字节(1 字节明文 + 标签 到 64KB + 标签)
  2. 密文数据 (变长):

    • GCM 加密后的数据
    • 自动包含 16 字节认证标签(在密文末尾)
    • 长度 = 原始数据长度 + 16

块索引与 Nonce:

每个数据块使用唯一的 nonce,生成规则:

块 nonce (12 字节) = 基础 nonce (12 字节) XOR (前4字节为0 + 块索引8字节)

例如:
基础 nonce:  [A0, A1, A2, A3, A4, A5, A6, A7, A8, A9, AA, AB]
块 0 索引:   [00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00]
块 0 nonce:  [A0, A1, A2, A3, A4, A5, A6, A7, A8, A9, AA, AB]

块 1 索引:   [00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 01]
块 1 nonce:  [A0, A1, A2, A3, A4, A5, A6, A7, A8, A9, AA, AA]

块 2 索引:   [00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 02]
块 2 nonce:  [A0, A1, A2, A3, A4, A5, A6, A7, A8, A9, AA, A9]

这确保了:

  • ✅ 每个块的 nonce 都唯一
  • ✅ 支持最多 2^64 个块
  • ✅ GCM 安全性要求得到满足

并行处理:

  • 加密时:多个工作线程并行加密不同块
  • 解密时:多个工作线程并行解密不同块
  • 结果排序:确保输出顺序正确
  • 工作线程数:默认等于 CPU 核心数
5. tar.xz 压缩数据

实际的文件/目录内容,经过以下处理:

  1. 使用 tar 格式打包
  2. 使用 xz (LZMA2) 算法压缩
  3. 然后进行 AES-GCM 加密(如果启用)

🔧 技术细节

Nonce 生成算法
// 为指定块索引生成唯一的 nonce
func generateNonce(blockIndex uint64, baseNonce []byte) []byte {
    nonce := make([]byte, 12)
    copy(nonce, baseNonce) // 复制基础 nonce (12 字节)
    
    // 将块索引转换为 8 字节
    indexBytes := make([]byte, 8)
    binary.BigEndian.PutUint64(indexBytes, blockIndex)
    
    // 与 nonce 的后 8 字节进行 XOR
    for i := 0; i < 8; i++ {
        nonce[4+i] ^= indexBytes[i]
    }
    
    return nonce
}
AES-GCM 加密
// 加密数据块(可变大小,≤64KB)
func AesGCMEncrypt(plaintext, key, nonce []byte) ([]byte, error) {
    block, err := aes.NewCipher(key)  // 256位密钥
    if err != nil {
        return nil, err
    }
    
    aesgcm, err := cipher.NewGCM(block)
    if err != nil {
        return nil, err
    }
    
    // Seal 会自动添加 16 字节认证标签
    ciphertext := aesgcm.Seal(nil, nonce, plaintext, nil)
    return ciphertext, nil
}
RSA 加密
// 加密 AES 配置(二进制格式)
func encryptConfig(a2 *A2, pubKey []byte) ([]byte, error) {
    block := struct {
        Nonce [12]byte
        Key   [32]byte
        Salt  [16]byte
    }{
        Nonce: [12]byte(a2.aes.Nonce),
        Key:   [32]byte(a2.aes.Key),
        Salt:  [16]byte(a2.aes.Salt),
    }
    
    var buf bytes.Buffer
    binary.Write(&buf, binary.BigEndian, block)
    
    return rsa.Encrypt(buf.Bytes(), pubKey)
}

📊 文件大小计算

加密文件大小
总大小 = 版本头 + 文件头 + RSA块 + 加密数据块总大小
      = 2 + 14 + 512 + Σ(4 + 块密文长度 + 16)

每个数据块:

块大小 = 4 (长度字段) + 明文大小 + 16 (GCM 标签)
示例
压缩数据大小 加密块数 每块大小 总文件大小
100 字节 1 4 + 100 + 16 = 120 648 字节
64 KB 1 4 + 65536 + 16 = 65556 66,084 字节
65 KB 2 65556 + 1044 = 66600 67,128 字节
1 MB 17 约 1,048,848 1,049,376 字节
10 MB 161 约 10,486,416 10,486,944 字节

开销分析:

  • 固定开销: 528 字节(版本头 + 文件头 + RSA块)
  • 每块开销: 20 字节(4字节长度 + 16字节标签)
  • 总开销率: (528 + 块数 × 20) / 总大小

对于大文件,开销率非常低(< 0.1%)。

未加密文件大小
总大小 = 版本头 + 文件头 + 压缩数据
      = 2 + 14 + 压缩数据大小

🚀 并行加密架构

AES-GCM vs AES-CBC
特性 A1 (AES-CBC) A2 (AES-GCM)
加密模式 CBC (密码块链接) GCM (伽罗瓦计数器)
认证 内置认证标签 (AEAD)
并行性 加密串行,解密可并行 加密和解密都并行
块大小 512 字节 64 KB
填充 随机填充 不需要填充
性能 中等 高 (多核优化)
安全性 更高 (防篡改)
IV/Nonce 固定 IV 每块唯一 nonce
Nonce 唯一性保证

GCM 模式下,nonce 必须唯一,否则会导致严重的安全问题。

A2 的 nonce 生成策略:

nonce (12 字节) = 随机基础nonce(12字节) XOR (0填充(4字节) + 块索引(8字节))
  • 基础 nonce:每次加密生成新的 12 字节随机数
  • 块索引:从 0 开始递增的 64 位整数

这确保了:

  1. 不同文件间 nonce 不同(随机基础 nonce)
  2. 同一文件内不同块 nonce 不同(块索引)
  3. 支持最多 2^64 个块(几乎无限)

🚀 并行加密优化

架构设计
                        ┌─────────────────┐
                        │  输入数据流      │
                        └────────┬─────────┘
                                 │
                    ┌────────────▼────────────┐
                    │   缓冲区 (64KB 块)       │
                    └────────────┬────────────┘
                                 │
                    ┌────────────▼────────────┐
                    │   任务队列 (16 缓冲)     │
                    └────────────┬────────────┘
                                 │
            ┌────────────────────┼────────────────────┐
            │                    │                    │
      ┌─────▼─────┐        ┌─────▼─────┐      ┌─────▼─────┐
      │  Worker 1 │        │  Worker 2 │ ...  │  Worker N │
      │  AES-GCM  │        │  AES-GCM  │      │  AES-GCM  │
      └─────┬─────┘        └─────┬─────┘      └─────┬─────┘
            │                    │                    │
            └────────────────────┼────────────────────┘
                                 │
                    ┌────────────▼────────────┐
                    │  结果排序 (保证顺序)     │
                    └────────────┬────────────┘
                                 │
                        ┌────────▼─────────┐
                        │  输出数据流       │
                        └──────────────────┘
工作流程
  1. 输入数据分块:将数据分成 64KB 的块
  2. 并行加密:多个工作线程同时加密不同的块
  3. 结果排序:按块索引顺序重新排列
  4. 顺序写入:确保输出文件块顺序正确
工作线程数

默认使用 runtime.NumCPU() 作为工作线程数,可以通过修改 numWorkers 常量调整。

性能提升

实际性能取决于数据大小、I/O 速度和 CPU 性能

📊 使用方法

并行模式

A2 版本默认且仅支持并行模式,自动利用多核 CPU 性能:

  • 自动检测 CPU 核心数
  • 启动对应数量的工作线程
  • 无需手动配置
使用 A2 版本压缩

main.go 中修改默认版本:

var defaultVersion = model.HeadVersion{
    Protocol: 'A',
    Version:  2,  // 使用 A2
}

或在命令行中通过参数指定(需要添加版本选择功能)。

🔧 性能调优

块大小调整

默认块大小为 64KB,可以根据场景调整:

// 小文件或低内存场景
blockSize = 1024 * 16  // 16KB

// 大文件或高性能场景
blockSize = 1024 * 256 // 256KB

建议

  • 小于 1MB 的文件:16-32KB
  • 1-100MB 的文件:64-128KB
  • 大于 100MB 的文件:128-256KB
队列大小调整

任务队列缓冲区大小影响内存使用和吞吐量:

// 低内存场景
queueSize = 4

// 高性能场景
queueSize = 32

🔒 安全性说明

GCM 认证加密 (AEAD)

AES-GCM 提供 AEAD (Authenticated Encryption with Associated Data)

自动认证: 每个数据块包含 16 字节认证标签
防篡改: 任何数据修改都会导致解密失败
完整性验证: 解密时自动验证数据未被篡改
并行友好: 认证和加密同时进行

工作原理:

  1. 加密时:Seal() 生成密文并附加 16 字节标签
  2. 解密时:Open() 验证标签,如果不匹配则返回错误
  3. 标签计算:基于密文、nonce、密钥和附加数据(如果有)

安全保证:

  • 数据保密性:攻击者无法读取明文
  • 数据完整性:任何修改都会被检测到
  • 数据真实性:确认数据来自持有密钥的一方
Nonce 唯一性保证

GCM 模式的核心安全要求:同一密钥下,nonce 必须唯一

A2 的 nonce 管理策略确保绝对唯一性:

  1. 随机基础 nonce (12 字节):

    • 每次加密文件时生成
    • 使用 crypto/rand 确保随机性
    • 存储在 RSA 加密块中
  2. 块索引 (64 位整数):

    • 从 0 开始递增
    • 每个块索引唯一
    • 支持 2^64 个块(理论上无限)
  3. XOR 组合:

    最终 nonce = 基础 nonce XOR (块索引的后8字节)
    

安全性证明:

  • 不同文件:基础 nonce 不同 → nonce 不同 ✅
  • 同一文件不同块:块索引不同 → nonce 不同 ✅
  • 重复加密同一文件:基础 nonce 重新生成 → nonce 不同 ✅

⚠️ 重要警告:

  • 不要修改 nonce 生成逻辑
  • 不要重用基础 nonce
  • 不要跳过或重复块索引

📝 使用建议

适用场景

A2 版本特别适合以下场景:

高性能需求

  • 处理大文件 (>100MB)
  • 需要快速加密/解密
  • 多核 CPU 环境
  • 有充足的内存资源

安全性要求高

  • 需要数据完整性验证
  • 防止数据篡改
  • 符合现代安全标准(AEAD)
  • 金融、医疗等敏感数据

批量处理

  • 大量文件并行处理
  • 自动化备份系统
  • CI/CD 流程集成
不适用场景

资源受限环境

  • 低内存设备 (< 4GB RAM)
  • 单核或双核 CPU
  • 嵌入式系统
  • 建议使用 A1 版本

超小文件

  • 文件小于 1MB
  • 并行开销大于收益
  • A1 版本可能更快
性能优化建议
  1. SSD 存储: A2 的高性能需要快速 I/O 支撑
  2. 多核 CPU: 至少 4 核以上才能发挥优势
  3. 充足内存: 建议至少 8GB RAM
  4. 调整块大小: 根据文件大小调整 blockSize 常量

🎯 未来优化方向

  1. 自适应块大小:根据文件大小自动调整块大小
  2. 内存池:减少 GC 压力,提高性能
  3. 零拷贝优化:减少内存分配和复制
  4. SIMD 加速:利用 CPU 向量指令加速 AES 计算
  5. GPU 加速:对超大文件使用 GPU 并行加密
  6. 流式处理:支持管道和流式数据源
  7. 增量压缩:只压缩变化的部分

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type A2

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

func (*A2) CheckPackage

func (a *A2) CheckPackage(in *bufio.Reader, encrypt *model.Encrypt) error

func (*A2) Compress

func (a *A2) Compress(in string, out *os.File, encrypt *model.Encrypt) error

func (*A2) Uncompress

func (a *A2) Uncompress(in *bufio.Reader, out string, encrypt *model.Encrypt) error

func (A2) Version

func (A2) Version() model.HeadVersion
type Head struct {
	IsEncryption bool
}

Jump to

Keyboard shortcuts

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