diff --git a/README.md b/README.md index 394746829..6d2a9eaa6 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@ Writes code, produces documents, and drives the desktop — with Mini Apps, a Rust runtime, and a self-hostable device-sync server. -[**⬇ Download for macOS · Windows · Linux**](https://github.com/GCWing/BitFun/releases/latest) +[**⬇ Download for macOS · Windows · Linux**](https://github.com/GCWing/BitFun/releases/latest) · [Verify downloads](./docs/verify-downloads.md) [Website](https://openbitfun.com/) · [Docs](./docs) · [Discussions](https://github.com/GCWing/BitFun/discussions) · [Contributing](./CONTRIBUTING.md) diff --git a/README.zh-CN.md b/README.zh-CN.md index 0b7d34899..0d03327a5 100644 --- a/README.zh-CN.md +++ b/README.zh-CN.md @@ -8,7 +8,7 @@ 能写代码、能做文档、能操控桌面,并提供小应用、Rust Runtime 和可自部署的多设备互控服务器。 -[**⬇ 下载 macOS · Windows · Linux 版**](https://github.com/GCWing/BitFun/releases/latest) +[**⬇ 下载 macOS · Windows · Linux 版**](https://github.com/GCWing/BitFun/releases/latest) · [校验下载](./docs/verify-downloads.zh-CN.md) [官网](https://openbitfun.com/) · [文档](./docs) · [讨论区](https://github.com/GCWing/BitFun/discussions) · [参与贡献](./CONTRIBUTING_CN.md) diff --git a/docs/verify-downloads.md b/docs/verify-downloads.md new file mode 100644 index 000000000..05584ed5a --- /dev/null +++ b/docs/verify-downloads.md @@ -0,0 +1,70 @@ +[中文](./verify-downloads.zh-CN.md) | **English** + +# Verify BitFun downloads + +Signed BitFun releases provide a detached `.sig` file for each covered +desktop installer or CLI archive. Release `v0.2.15`, for example, provides +signatures for its desktop and CLI downloads. + +BitFun uses this pinned minisign public key: + +- Key ID: `50F47CBE6CC0A376` +- Public key: `RWR2o8Bsvnz0UOBc3NoTVW06wdiGM7pLP3LpiL4A3Sp4nxkBsWlJRTxn` + +The same key is published as `minisign.pub` with signed releases and is built +into official BitFun update paths. The commands below pin the key directly so +the signature and key are not both trusted only because they came from the same +download location. + +## macOS or Linux + +Install [minisign](https://github.com/jedisct1/minisign/releases), then run the +following in a new empty directory. Replace both values with the exact tag and +asset name shown on the release page when verifying another download. + +```bash +VERSION=v0.2.15 +ASSET=bitfun-cli-0.2.15-aarch64-unknown-linux-gnu.tar.gz +BASE="https://github.com/GCWing/BitFun/releases/download/$VERSION" +PUBLIC_KEY=RWR2o8Bsvnz0UOBc3NoTVW06wdiGM7pLP3LpiL4A3Sp4nxkBsWlJRTxn + +curl --fail --location --remote-name "$BASE/$ASSET" +curl --fail --location --remote-name "$BASE/$ASSET.sig" +base64 --decode <"$ASSET.sig" >"$ASSET.minisig" +minisign -Vm "$ASSET" -P "$PUBLIC_KEY" -x "$ASSET.minisig" +``` + +A valid download prints `Signature and comment signature verified` and exits +with status 0. Do not run or install the asset if verification fails. + +## Windows PowerShell + +Install minisign, open a new empty directory, and use the exact release tag and +asset name you downloaded: + +```powershell +$Version = "v0.2.15" +$Asset = "BitFun_0.2.15_windows-x86_64-setup.exe" +$Base = "https://github.com/GCWing/BitFun/releases/download/$Version" +$PublicKey = "RWR2o8Bsvnz0UOBc3NoTVW06wdiGM7pLP3LpiL4A3Sp4nxkBsWlJRTxn" + +Invoke-WebRequest "$Base/$Asset" -OutFile $Asset +Invoke-WebRequest "$Base/${Asset}.sig" -OutFile "${Asset}.sig" +$EncodedSignature = (Get-Content "${Asset}.sig" -Raw).Trim() +[IO.File]::WriteAllBytes("${Asset}.minisig", [Convert]::FromBase64String($EncodedSignature)) +minisign -Vm $Asset -P $PublicKey -x "${Asset}.minisig" +if ($LASTEXITCODE -ne 0) { throw "BitFun download signature verification failed" } +``` + +## What the `.sig` file means + +BitFun release `.sig` files are base64-wrapped **minisign signatures**. Decode +one layer before giving the result to the minisign CLI, as shown above. A valid +signature proves that the file's exact bytes match a signature made by the +pinned BitFun release key; changing even one byte makes verification fail. + +This is not platform code signing. In particular, a BitFun `.sig` is not an +Apple Developer ID signature or notarization ticket, and it is not Windows +Authenticode. Gatekeeper and SmartScreen can therefore show their own warnings +independently of a successful minisign check. Signature verification also does +not replace your normal review of the software and its dependencies. diff --git a/docs/verify-downloads.zh-CN.md b/docs/verify-downloads.zh-CN.md new file mode 100644 index 000000000..d6b46fc47 --- /dev/null +++ b/docs/verify-downloads.zh-CN.md @@ -0,0 +1,67 @@ +**中文** | [English](./verify-downloads.md) + +# 校验 BitFun 下载文件 + +带签名的 BitFun Release 会为覆盖到的桌面安装包或 CLI 归档提供独立的 +`<文件名>.sig`。例如,`v0.2.15` 已为桌面端和 CLI 下载文件提供签名。 + +BitFun 固定使用以下 minisign 公钥: + +- Key ID:`50F47CBE6CC0A376` +- 公钥:`RWR2o8Bsvnz0UOBc3NoTVW06wdiGM7pLP3LpiL4A3Sp4nxkBsWlJRTxn` + +带签名的 Release 还会发布包含同一把公钥的 `minisign.pub`,BitFun 官方更新 +路径也内置了这把公钥。下面的命令直接固定公钥,避免仅仅因为签名和公钥来自 +同一个下载位置就同时信任两者。 + +## macOS 或 Linux + +先安装 [minisign](https://github.com/jedisct1/minisign/releases),然后在一个新建 +的空目录中运行以下命令。校验其他版本时,请将两个变量同时替换为 Release 页面 +显示的准确 tag 和文件名。 + +```bash +VERSION=v0.2.15 +ASSET=bitfun-cli-0.2.15-aarch64-unknown-linux-gnu.tar.gz +BASE="https://github.com/GCWing/BitFun/releases/download/$VERSION" +PUBLIC_KEY=RWR2o8Bsvnz0UOBc3NoTVW06wdiGM7pLP3LpiL4A3Sp4nxkBsWlJRTxn + +curl --fail --location --remote-name "$BASE/$ASSET" +curl --fail --location --remote-name "$BASE/$ASSET.sig" +base64 --decode <"$ASSET.sig" >"$ASSET.minisig" +minisign -Vm "$ASSET" -P "$PUBLIC_KEY" -x "$ASSET.minisig" +``` + +校验成功时会输出 `Signature and comment signature verified`,并以状态码 0 退出。 +如果校验失败,请不要运行或安装该文件。 + +## Windows PowerShell + +安装 minisign 后,打开一个新建的空目录,并使用你所下载文件对应的准确 Release +tag 和文件名: + +```powershell +$Version = "v0.2.15" +$Asset = "BitFun_0.2.15_windows-x86_64-setup.exe" +$Base = "https://github.com/GCWing/BitFun/releases/download/$Version" +$PublicKey = "RWR2o8Bsvnz0UOBc3NoTVW06wdiGM7pLP3LpiL4A3Sp4nxkBsWlJRTxn" + +Invoke-WebRequest "$Base/$Asset" -OutFile $Asset +Invoke-WebRequest "$Base/${Asset}.sig" -OutFile "${Asset}.sig" +$EncodedSignature = (Get-Content "${Asset}.sig" -Raw).Trim() +[IO.File]::WriteAllBytes("${Asset}.minisig", [Convert]::FromBase64String($EncodedSignature)) +minisign -Vm $Asset -P $PublicKey -x "${Asset}.minisig" +if ($LASTEXITCODE -ne 0) { throw "BitFun 下载文件签名校验失败" } +``` + +## `.sig` 文件代表什么 + +BitFun Release 的 `.sig` 是经过一层 base64 包装的 **minisign 签名**。交给 +minisign 命令行工具之前,需要像上面的命令一样先解码一层。校验成功表示文件的 +每个字节都与 BitFun 固定发布公钥对应的签名一致;哪怕只修改一个字节,校验也会 +失败。 + +这不是操作系统级代码签名。BitFun 的 `.sig` 既不是 Apple Developer ID 签名或 +公证票据,也不是 Windows Authenticode。因此,即使 minisign 校验成功,Gatekeeper +或 SmartScreen 仍可能独立显示提示。签名校验也不能替代你对软件及其依赖的正常 +审查。