secra-pluginctl

Crates.iosecra-pluginctl
lib.rssecra-pluginctl
version0.2.0
created_at2025-12-24 13:26:13.703914+00
updated_at2025-12-24 13:26:13.703914+00
description生产级插件打包工具 - 安全可信的插件产物管理(支持加密、签名、并发处理)
homepagehttps://github.com/BadassFree/secra-pluginctl
repositoryhttps://github.com/BadassFree/secra-pluginctl
max_upload_size
id2003170
size116,310
(BadassFree)

documentation

https://github.com/BadassFree/secra-pluginctl

README

Secra PluginCtl

生产级、安全可信的插件打包工具 - Production-Grade Secure Plugin Packaging Tool

Crates.io License: MIT

🎯 核心特性

  • 🔒 高安全性:基于 ring 加密库,支持 AES-256-GCM 加密和 Ed25519 数字签名
  • 📦 单一产物:多源输入打包为不可拆分的 .spk 二进制文件
  • 🚀 高性能:使用 zstd 压缩和 rayon 并发处理,优化的二进制格式
  • 🔧 灵活配置:支持 Glob 模式、可配置压缩级别、依赖管理
  • 🌍 跨平台:纯 Rust 实现,支持 Windows / macOS / Linux
  • 📚 库 + CLI:既可作为库嵌入,也可独立使用

🚀 快速开始

安装

cargo install secra-pluginctl

作为 CLI 使用

# 1. 初始化配置文件
pluginctl init --name com.example.my-plugin

# 2. 编辑 plugin.toml 配置文件

# 3. 生成密钥对
pluginctl keygen

# 4. 打包插件
pluginctl pack

# 5. 验证产物
pluginctl verify --input dist/my-plugin.spk --public-key public_key.pem

# 6. 解包(需要公钥验证)
pluginctl unpack --input dist/my-plugin.spk --output unpacked --public-key public_key.pem

作为库使用

use secra_pluginctl::{PluginConfig, Packer};

fn main() -> anyhow::Result<()> {
    // 从配置文件加载
    let config = PluginConfig::from_file("plugin.toml")?;
    
    // 构建打包器
    let packer = Packer::new(config)?;
    
    // 执行打包
    let output_path = packer.pack("output.spk")?;
    
    println!("打包成功: {}", output_path.display());
    Ok(())
}

📖 配置示例

[metadata]
name = "com.example.my-plugin"
version = "1.0.0"
description = "插件描述"
authors = ["Your Name <email@example.com>"]

# 依赖项(可选)
[metadata.dependencies]
example-lib = "^1.0.0"

[build]
input = "./src"
output_dir = "./dist"
include = ["**/*"]
exclude = ["**/node_modules/**", "**/.git/**"]

[build.compression]
enabled = true
level = 10  # 1-22

[crypto]
private_key = "private_key.pem"
system_public_key = "public_key.pem"

🏗️ 产物格式(.spk)

┌────────────────────────────────────────┐
│ Magic Header: "SECRAPKG"               │  8 bytes
├────────────────────────────────────────┤
│ Format Version: u32                    │  4 bytes
├────────────────────────────────────────┤
│ Metadata Length: u32                   │  4 bytes
├────────────────────────────────────────┤
│ Metadata (JSON)                        │
│  - package_id (UUID)                   │
│  - name, version, authors              │
│  - created_at, dependencies            │
│  - file manifest, signatures           │
├────────────────────────────────────────┤
│ Encrypted Data (AES-256-GCM)           │
│  - Compressed payload (zstd)           │
│  - All file contents                   │
└────────────────────────────────────────┘

🔐 安全特性

  1. 数据加密:AES-256-GCM 对称加密,保护插件内容
  2. 数字签名:Ed25519 签名,验证来源和完整性
  3. 指纹验证:SHA-256 哈希,防止篡改
  4. 密封格式:自定义二进制格式,仅本工具可解析
  5. 包唯一 ID:UUID v4 标识,便于追踪管理

📊 性能指标

  • 压缩速度: ~500 MB/s (zstd level 10)
  • 哈希计算: ~1 GB/s (SHA-256, ring)
  • 并发处理: 支持 rayon 多核并行
  • 加密速度: ~1 GB/s (AES-256-GCM, ring)

🔧 CLI 命令

命令 说明
init 初始化配置文件
pack 打包插件
unpack 解包插件(需要公钥验证)
keygen 生成密钥对
verify 验证插件签名
inspect 检查插件内容(列出文件列表并验证格式)

📖 使用方法

完整工作流程

1. 初始化项目

# 创建插件项目并初始化配置
pluginctl init --name com.example.my-plugin

这会创建一个 plugin.toml 配置文件,包含基本的项目元数据和构建配置。

2. 配置项目

编辑 plugin.toml 文件,设置以下内容:

  • metadata: 插件名称、版本、描述、作者等信息
  • build: 输入目录、输出目录、包含/排除文件模式
  • crypto: 私钥和公钥路径

3. 生成密钥对

# 生成 Ed25519 密钥对
pluginctl keygen

# 这会生成两个文件:
# - private_key.pem: 私钥(用于签名和加密)
# - public_key.pem: 公钥(用于验证)

安全提示: 请妥善保管私钥,不要将其提交到版本控制系统。

4. 打包插件

# 使用默认配置打包
pluginctl pack

# 或者指定配置文件
pluginctl pack --config custom.toml

# 打包后的文件会输出到配置中指定的 output_dir 目录

打包过程会:

  • 收集所有匹配的文件
  • 计算文件哈希
  • 压缩数据
  • 加密内容
  • 生成数字签名
  • 输出 .spk 文件

5. 验证插件

# 验证插件签名和完整性
pluginctl verify --input dist/my-plugin.spk --public-key public_key.pem

验证会检查:

  • 文件格式是否正确
  • 数字签名是否有效
  • 文件哈希是否匹配

6. 检查插件内容

# 查看插件内容(不需要私钥)
pluginctl inspect --input dist/my-plugin.spk

这会列出:

  • 插件元数据(名称、版本等)
  • 包含的文件列表
  • 文件大小和哈希值

7. 解包插件

# 解包插件到指定目录(需要公钥验证)
pluginctl unpack \
  --input dist/my-plugin.spk \
  --output unpacked \
  --public-key public_key.pem

解包过程会:

  • 验证签名
  • 解密数据
  • 解压缩内容
  • 恢复所有文件到原始目录结构

高级用法

自定义压缩级别

plugin.toml 中配置:

[build.compression]
enabled = true
level = 15  # 1-22,数字越大压缩率越高但速度越慢

使用 Glob 模式过滤文件

[build]
include = ["**/*.js", "**/*.css", "**/*.html"]  # 只包含特定类型文件
exclude = ["**/test/**", "**/*.map", "**/.DS_Store"]  # 排除测试文件和临时文件

在代码中使用

use secra_pluginctl::{PluginConfig, Packer, Unpacker};

// 打包
let config = PluginConfig::from_file("plugin.toml")?;
let packer = Packer::new(config)?;
let output = packer.pack("output.spk")?;

// 解包
let public_key = std::fs::read("public_key.pem")?;
let unpacker = Unpacker::new("output.spk", &public_key)?;
unpacker.unpack("unpacked_dir")?;

常见问题

Q: 打包时提示找不到密钥文件?
A: 确保 plugin.toml 中的 crypto.private_key 路径正确,或使用 keygen 命令生成密钥对。

Q: 如何更新插件版本?
A: 修改 plugin.toml 中的 metadata.version 字段,然后重新打包。

Q: 可以打包多个目录吗?
A: 当前版本支持单个输入目录,可以使用符号链接或构建脚本合并多个目录。

Q: 解包时需要私钥吗?
A: 不需要,解包只需要公钥进行验证。私钥仅用于打包时的签名和加密。

📚 技术栈

组件 技术 理由
加密/签名 ring BoringSSL 基础,经过严格审计
压缩 zstd 现代压缩算法,速度和压缩比最优
并发 rayon 数据并行,充分利用多核
文件匹配 globset 高效的 Glob 模式匹配
序列化 serde Rust 生态标准
CLI clap 现代 CLI 框架

🆕 版本 0.2.0 更新

  • ✅ 支持 Glob 模式匹配(include/exclude)
  • ✅ 并发处理(rayon 多线程)
  • ✅ 可配置压缩级别(1-22)
  • ✅ 依赖管理支持
  • ✅ init 命令快速上手
  • ✅ 包唯一 ID(UUID)
  • ✅ 简化数据结构(移除分类)
  • ✅ 升级产物格式到 v2

🛠️ 开发

# 构建
cargo build --release

# 测试
cargo test

# 运行示例
cargo run --example basic

# 打包
cargo package

📄 License

MIT License - 详见 LICENSE 文件

🤝 贡献

欢迎提交 Issue 和 Pull Request!


注意: 本工具主要用于内部使用,生产环境使用前请确保实现完整的 RSA-OAEP 密钥加密方案。

Commit count: 0

cargo fmt