-
Notifications
You must be signed in to change notification settings - Fork 0
OpenPGP Signing
SDK
0.2.4。正式分发的.pnp必须签名。
PCL N 使用 OpenPGP detached signature 验证发布者身份和包内容。推荐 Ed25519 主密钥与签名子密钥,也支持 RSA 3072 位及以上。SHA-1、过期或吊销密钥会被拒绝。
开发构建同样不会生成未签名包。PclNPluginSign=false 表示由 SDK 创建并使用仅限本机的开发密钥;该包可以手动安装测试,但不能作为插件中心候选包。
gpg --version使用 GnuPG 2.x。Windows 可安装 Gpg4win;Linux/macOS 使用系统包管理器。
交互方式:
gpg --full-generate-key为插件发布使用独立密钥,设置强密码并妥善备份撤销证书。发布者团队应明确谁可以使用签名子密钥。
gpg --list-secret-keys --with-subkey-fingerprint --keyid-format long把主密钥完整指纹写进 Manifest。单签插件只需要 fingerprint:
"signing": {
"fingerprint": "0123456789ABCDEF0123456789ABCDEF01234567"
}团队多签或轮换期间可以同时声明多个 active key,并用 minimumValidSignatures 要求至少多少个签名通过:
"signing": {
"fingerprint": "0123456789ABCDEF0123456789ABCDEF01234567",
"fingerprints": [
"89ABCDEF0123456789ABCDEF0123456789ABCDEF"
],
"revokedFingerprints": []
},
"signingPolicy": {
"minimumValidSignatures": 2,
"roles": ["maintainer", "release"]
}不要使用 8/16 位短 Key ID,也不要写空格。revokedFingerprints 中的 key 会被运行时和插件中心拒绝,即使包内仍带有对应签名。
<PropertyGroup>
<PclNPluginSign>true</PclNPluginSign>
<PclNPluginGpgPath>gpg</PclNPluginGpgPath>
</PropertyGroup>dotnet build -c Release构建器会:
- 对
META-INF/pnp.signed.json创建 armored detached signature; - 为 Manifest 中每个 active signing fingerprint 写入
META-INF/signatures/<fingerprint>.asc; - 导出对应公钥到
META-INF/keys/<fingerprint>.asc; - 在 signed payload 中写入
signingKeyFingerprints; - 让文件表和 payload root 覆盖包内容。
.pnp 是 ZIP,可复制到临时目录后解压查看:
Copy-Item .\bin\Release\net10.0\dev.example.plugin-1.0.0.pnp plugin.zip
Expand-Archive .\plugin.zip .\plugin-inspect
Get-ChildItem .\plugin-inspect\META-INF -Recurse不要修改并重新压缩正式包;任何内容变化都会破坏哈希或签名。
将私钥保存在 CI 的加密 Secret 中,运行时导入临时 GPG home。不要把私钥、密码、导出文件或 Secret 输出到日志。
- name: Import signing key
shell: bash
env:
PNP_GPG_PRIVATE_KEY: ${{ secrets.PNP_GPG_PRIVATE_KEY }}
run: |
set -euo pipefail
printf '%s' "$PNP_GPG_PRIVATE_KEY" | gpg --batch --import
- name: Build signed package
run: dotnet build -c Release -p:PclNPluginSign=true若密钥有密码,使用支持非交互 pinentry 的安全方案,并把密码放在独立 Secret。不要使用 --passphrase 把明文暴露在进程列表或日志中。
上传时,你的 .pnp 是“开发者自签名候选包”。插件中心会重新完成文件表、逐文件哈希、payload root、公钥完整指纹和 detached signature 验证。审核通过后,候选包不会直接分发;网站会保留原始负载与开发者签名,并追加:
META-INF/market/pcln-market-v1.json
META-INF/market/signatures/<market-fingerprint>.asc
META-INF/market/keys/<market-fingerprint>.asc
网站签名封套绑定候选包 SHA-256、payload root、插件 ID/版本、开发者指纹、审核记录与时间。网站私钥只保存在服务端 Secret/HSM,不会下发到开发者后台或浏览器。
从插件中心安装时,PCL 会先验证包内两层 OpenPGP 签名,再将最终分发包 SHA-256、插件 ID/版本和两个指纹发送到 POST /v1/packages/verify。接口必须明确返回当前状态为 published;包已吊销、记录不匹配、网络失败或服务不可用都会拒绝安装。手动安装开发包不会获得“市场已审核”标记。
- 用旧密钥发布说明新指纹的版本或公告。
- 在插件中心完成发布者密钥验证。
- 新版本 Manifest 改用新完整指纹。
- 保留旧公钥用于验证历史版本。
- 密钥泄露时立即吊销,并停止分发所有受影响版本。