aslancarlos/codesign-workshop
GitHub: aslancarlos/codesign-workshop
一个交互式终端工坊,通过 PKCS#11 接口现场演示云端 HSM 支持的代码签名全流程,涵盖密钥保护、职责分离与治理审计等安全特性。
Stars: 0 | Forks: 0
# 代码签名工坊 (PKCS#11 → 云端 HSM)
[](https://github.com/aslancarlos/codesign-workshop/actions/workflows/shellcheck.yml)
[](LICENSE)
[](https://www.gnu.org/software/bash/)
[](https://www.shellcheck.net/)
[](#)
这是一个交互式、菜单驱动的终端**工坊**,它通过 **PKCS#11** 接口针对云端 Code Sign Manager 服务(例如 **CyberArk Code Sign Manager – SaaS**,前身为 *Venafi CodeSign Protect*),现场演示了**由 HSM 支持的代码签名**是如何工作的。
这个工坊的核心目的是一步步**证明**在签署软件时至关重要的安全特性:
- 🔒 **私钥永不离开 HSM。** 工具仅发送 *hash*;签名结果随后返回。工坊甚至会尝试导出密钥并展示 HSM 拒绝该操作的过程。
- ✍️ **真实、可验证的签名。** 它使用 `jarsigner` 对真实的 `.jar` 进行签名,并使用 `openssl` 生成真实的 CMS/PKCS#7 签名,然后使用它们原生的工具对两者进行验证。
- 👥 **职责分离。** 作为项目*所有者*并**不**授予签名权限——只有*授权的签名者*身份才能使用这些密钥。
- 🧾 **治理与不可抵赖性。** 它通过平台 API 获取每个密钥的签名计数器,并在本地保留其执行的每个签名的详细日志(时间戳、身份、密钥、工具、制品、SHA-256)。
交互式 UI 提供**葡萄牙语 和西班牙语**版本。
本文档为英文版本。
## 目录
- [工作原理](#how-it-works)
- [环境要求](#requirements)
- [配置](#configuration)
- [运行工坊](#running-the-workshop)
- [具体步骤](#the-steps)
- [架构](#architecture)
- [安全说明](#security-notes)
- [故障排除](#troubleshooting)
- [贡献](#contributing)
- [许可证](#license)
## 工作原理
构建机器上的签名工具与 **PKCS#11 module**(Code Sign Manager 客户端库,例如 `venafipkcs11.so`)进行通信。该模块将 hash 转发给云服务,云服务在 **HSM** 内部执行签名操作并返回签名。客户端上永远不会存在私钥材料。
```
build machine PKCS#11 module Cloud HSM
(jarsigner/openssl) ──hash──► (vendor .so) ──hash──► [ private key ]
◄─sig─── ◄─sig──── 🔒 never leaves
```
身份通过 **grant**(通过客户端的 `login` 获取)向服务进行身份验证。只有作为包含签名密钥项目的**授权签名者**,这些身份才能看到密钥。
## 环境要求
该工坊是一个可移植的 `bash` 脚本。要体验**每一个**步骤,你需要:
| 工具 | 用于 | 必需 |
|------|----------|----------|
| `bash` (4+) | 工坊本身 | ✅ |
| Code Sign Manager **PKCS#11 client**(提供 `pkcs11config` + `.so`) | 登录、列出、签名、获取证书 | ✅ |
| 带有 **pkcs11 engine**(`libpkcs11.so` / `engines-3/pkcs11.so`)的 `openssl` (3.x) | CMS 签名与验证 | 可选步骤 |
| `jarsigner` + `keytool` (JDK 11+) | 真实的 JAR 签名及“密钥保留在 HSM 中”的证明 | 可选步骤 |
| `python3` | 格式化 API/清单输出 | 可选步骤 |
| `curl` | 基于 API 的步骤(计数、签名者) | 可选步骤 |
如果缺少某个工具,相应步骤会优雅降级并给出提示;工坊的其余部分仍会继续运行。
## 配置
所有内容都通过**环境变量**进行配置——没有硬编码的身份、密钥、租户或标签。复制模板并进行调整:
```
cp .env.example .env
# 编辑 .env,然后:
set -a; . ./.env; set +a
./codesign-workshop.sh
```
| 变量 | 默认值 | 描述 |
|----------|---------|-------------|
| `CLIENT_ID` | *(空)* | 用于登录的服务账号 UUID(登录步骤必需) |
| `KEYFILE` | `$HOME/.codesign/service_account.key` | 服务账号私钥 (PEM) |
| `API_TOKEN_FILE` | `$HOME/.codesign/api_token` | 包含 API 密钥的文件;启用基于 API 的步骤 |
| `LABEL_SIGN` | `signing-key` | 签名密钥标签(如 `pkcs11config list` 所示) |
| `LABEL_CERT` | `$LABEL_SIGN` | 要下载的证书标签 |
| `PROJECT` | `my-project` | Code Sign 项目名称(用于 API 查询和控制台提示) |
| `IDENTITY` | `signer` | 签名身份的友好显示名称 |
| `TENANT` | *(空)* | 租户 / URL 前缀(设置后仅在控制台提示中显示) |
| `API_BASE` | `https://api.venafi.cloud` | API 区域基 URL(默认为美国;EU/AU/UK/SG/CA 有所不同) |
| `BRAND` | `Machine Identity - Code Signing Workshop` | 横幅 / 标题文本 |
| `MODULE` | `/opt/venafi/codesign/lib/venafipkcs11.so` | PKCS#11 module 的路径 |
| `ENGINE_SO` | `/usr/lib/x86_64-linux-gnu/engines-3/pkcs11.so` | OpenSSL pkcs11 engine 的路径 |
| `PKCS11_PIN` | `1234` | PKCS#11 PIN — 一个虚拟值;真正的认证是云端 grant |
| `WORK` | `/tmp/codesign_demo` | 生成制品的工作目录 |
| `DEMO_LANG` | *(询问)* | `pt` 或 `es`;如果为空,工坊在启动时会进行询问 |
## 运行工坊
```
./codesign-workshop.sh # asks for language, then shows the menu
DEMO_LANG=es ./codesign-workshop.sh # start directly in Spanish
```
从菜单中选择步骤,或按 **`g`** 运行完整的引导脚本
(开场 → 价值回顾)。按 **`l`** 可随时切换语言。
## 具体步骤
| # | 步骤 | 演示内容 |
|---|------|----------------------|
| i | 开场 | 业务问题 + 架构图 |
| 1 | 前置条件 | 客户端版本和 grant 有效性 |
| 2 | 登录 | 以服务账号身份进行认证 (机器身份) |
| 3 | 职责分离 | 所有者什么也看不到;授权签名者可以看到密钥 |
| 4 | 列出 | 同步到客户端的密钥/证书引用 |
| 5 | 密钥保留在 HSM 中 | 导出尝试被**拒绝** (不可提取) |
| 6 | 获取证书 | 仅下载公共证书 + 证书链 |
| 7 | 签名 JAR | 真实的 `jarsigner` 签名,原生验证 |
| 8 | 签名 CMS/PKCS#7 | 真实的 `openssl` 签名 + 往返延迟 |
| 9 | 完整性与防篡改 | 正向验证 + 篡改检测 |
| 10 | 治理 | 通过 API 获取的核心密钥清单 + 签名者 |
| 11 | 签名与日志 | 每个密钥的计数器 + 最后 5 条详细签名记录 |
| 12 | 价值回顾 | 证明点 + 合规性映射 |
每个签名步骤(7、8、9)都会打印一张 **ASCII 流程图**,展示工具如何通过 PKCS#11 连接到 HSM,并向步骤 11 中显示的本地会话日志追加一条记录。
## 架构
请参阅 [`docs/ARCHITECTURE.md`](docs/ARCHITECTURE.md) 了解数据流图和身份/授权模型。
## 安全说明
请参阅 [`SECURITY.md`](SECURITY.md)。简而言之:切勿提交私钥或 API token;工坊会将生成的制品(以及包含服务账号显示名称和制品 hash 的会话签名日志)写入 `WORK` 目录——体验完成后,请使用菜单中的 *cleanup* 选项将其清理干净。
## 故障排除
请参阅 [`docs/USAGE.md`](docs/USAGE.md#troubleshooting)。最常见的问题是 `list` 为空:这意味着经过认证的身份不是包含*就绪*密钥项目的**授权签名者**——请在控制台中修复此问题,然后使用 `--force` 重新登录。
## 开发
本工坊**以模块形式开发**,位于 `src/` 目录下,并**作为单个独立文件** (`codesign-workshop.sh`) 分发,以便可以将其复制到目标机器上运行,无需额外文件。
```
# 编辑 src/ 下的模块,然后重新生成可分发包:
./build.sh
# 验证其是否同步(这是 CI 运行的内容):
./build.sh --check
```
**请勿**手动编辑 `codesign-workshop.sh` ——它是生成的。请参阅
[`CONTRIBUTING.md`](CONTRIBUTING.md#project-layout) 了解模块映射。
## 贡献
欢迎贡献——请参阅 [`CONTRIBUTING.md`](CONTRIBUTING.md) 和
[`CODE_OF_CONDUCT.md`](CODE_OF_CONDUCT.md)。
## 许可证
[MIT](LICENSE)。
标签:Bash, HSM, PKCS#11, 代码签名, 安全培训, 安全测试工具, 密码学, 应用安全, 手动系统调用, 逆向工具