- 区块链
- 开发框架
- 后端
【免费下载链接】substrate
Substrate: The platform for blockchain innovators
subkey是 Substrate 官方提供的一站式密钥管理命令行工具,面向 Substrate 生态链(如 Polkadot、Kusama 以及各类平行链和 Substrate 项目)的开发者与用户。本文以仓库中 scripts/ci/docker/subkey.Dockerfile.README.md 对 subkey 的能力定义为主线,结合 bin/utils/subkey/README.md、bin/utils/subkey/SECURITY.md 与 scripts/ci/docker/subkey.Dockerfile 等仓库资料,系统讲解如何生成与检查密钥对、从助记词和原始种子恢复密钥、对消息进行签名与验证、派生分层确定性子密钥,以及如何通过 Docker 容器安全地使用该工具。读完本文,你将能够独立完成 Substrate 链账户密钥的全生命周期管理,并掌握容器化部署与安全实践要点。
认识 subkey:Substrate 生态的密钥管理工具
Substrate 官方文档对subkey的定位是:"Thesubkeyprogram is a key management utility for Substrate-based blockchains"——即面向 Substrate 系区块链的密钥管理工具。根据仓库中 scripts/ci/docker/subkey.Dockerfile.README.md 的定义,你可以使用 subkey 完成以下任务:
- 生成并检查密码学安全的公钥/私钥对;
- 从助记词(secret phrase)和原始种子(raw seed)恢复密钥;
- 对消息进行签名与验签;
- 对编码后的交易进行签名与验签;
- 派生分层确定性(Hierarchical Deterministic, HD)子密钥对。
从源码结构看,subkey 的完整实现位于仓库的 bin/utils/subkey/ 目录。其中 Cargo.toml 声明了subkey3.0.0 这个独立的二进制 crate,入口为 src/main.rs,其核心逻辑极简——main()直接调用subkey::run(),全部功能通过 src/lib.rs 实现,命令行解析依赖clap 4.2.5(启用derive特性),错误类型则复用sc-cli(client/cli)的定义。也就是说,subkey 实际上是 Substrate 客户端 CLI 工具链在密钥管理场景下的专门化封装。
完全离线的密钥工具
subkey 在运行时不需要联网。这一点既是设计特性,也是安全要求:密钥操作不涉及任何网络请求,因此你可以(也应该)在完全断网的机器上生成和管理密钥。正如 bin/utils/subkey/README.md 强调的:"for the best security, you should be usingsubkeyon a machine that isnot connectedto the internet."
安装与获取 subkey
subkey 的获取方式有两种:通过 Cargo 从源码安装,或直接使用官方发布的 Docker 容器镜像。
通过 Cargo 安装
使用cargo install可以只安装subkey这一个工具,而无需编译整个节点。仓库给出的推荐命令如下:
# 安装指定版本的 subkey crate cargo install --force subkey --git https://github.com/paritytech/substrate --version <SET VERSION> --locked--force:覆盖已安装的旧版本;--version <SET VERSION>:指定 subkey crate 的版本号(例如本仓库中的 3.0.0);--locked:使用仓库Cargo.lock中锁定的依赖版本,保证构建可复现。
需要说明的是,从源码安装 subkey 需要先具备 Substrate 的构建依赖环境;如果构建过程中报错,通常是因为缺少系统级依赖。
在 Docker 容器中运行
对于不想本地编译、又希望隔离运行环境的场景,官方在 Docker Hub 发布了parity/subkey镜像,直接运行即可:
docker run -it --pull=always docker.io/parity/subkey:latest <command to subkey>- 使用
latest标签时建议配合--pull=always,确保拉取到最新镜像; - 也可以改用指定版本的标签来固定版本;
<command to subkey>即你要执行的 subkey 子命令,例如subkey generate。
官方镜像的构建细节:解析 subkey.Dockerfile
仓库中 scripts/ci/docker/subkey.Dockerfile 正是构建该官方镜像的 Dockerfile,它从侧面揭示了 subkey 容器的运行模型:
FROM docker.io/library/ubuntu:20.04 # metadata ARG VCS_REF ARG BUILD_DATE ARG IMAGE_NAME LABEL io.parity.image.authors="devops-team@parity.io" \ io.parity.image.vendor="Parity Technologies" \ io.parity.image.title="${IMAGE_NAME}" \ io.parity.image.description="Subkey: key generating utility for Substrate." \ io.parity.image.source="https://github.com/paritytech/substrate/blob/${VCS_REF}/scripts/ci/docker/subkey.Dockerfile" \ io.parity.image.revision="${VCS_REF}" \ io.parity.image.created="${BUILD_DATE}" \ io.parity.image.documentation="https://github.com/paritytech/substrate/tree/${VCS_REF}/subkey" # show backtraces ENV RUST_BACKTRACE 1 # add user RUN useradd -m -u 1000 -U -s /bin/sh -d /subkey subkey # add subkey binary to docker image COPY ./subkey /usr/local/bin USER subkey # check if executable works in this container RUN /usr/local/bin/subkey --version ENTRYPOINT ["/usr/local/bin/subkey"]这份 Dockerfile 的几个关键点值得留意:
- 基础镜像与元数据:基于
ubuntu:20.04,通过构建参数VCS_REF、BUILD_DATE、IMAGE_NAME注入版本、构建时间与镜像名,并写入 OCI Label,用于镜像溯源与审计。 - 非 root 运行:创建了 UID 1000、无密码、家目录为
/subkey的专用用户subkey,并以USER subkey切换,容器内进程默认不具备 root 权限——这符合密钥工具"最小权限"的安全惯例。 - ENTRYPOINT 直接指向二进制:容器的入口就是
/usr/local/bin/subkey,因此docker run ... subkey generate等价于直接执行subkey generate。 - 构建期自检:
RUN /usr/local/bin/subkey --version在构建阶段就验证二进制在当前容器内可执行,避免发布坏镜像。
生成加密安全的密钥对
生成随机账户
生成一个新密钥对只需一条命令:
subkey generate输出类似(以下均为示例数据,切勿复用本文出现的任何种子与助记词):
Secret phrase `hotel forest jar hover kite book view eight stuff angle legend defense` is account: Secret seed: 0xa05c75731970cc7868a2fb7cb577353cd5b31f62dccced92c441acd8fee0c92d Public key (hex): 0xfec70cfbf1977c6965b5af10a4534a6a35d548eb14580594d0bc543286892515 Account ID: 0xfec70cfbf1977c6965b5af10a4534a6a35d548eb14580594d0bc543286892515 SS58 Address: 5Hpm9fq3W3dQgwWpAwDS2ZHKAdnk86QRCu7iX4GnmDxycrte输出字段解读
generate输出的五类信息需要分清"秘密"与"公开"的边界:
| 字段 | 性质 | 说明 |
|---|---|---|
| Secret phrase(助记词) | 秘密 | 即 mnemonic phrase,默认 12 个单词,必须妥善保密 |
| Secret seed(秘密种子) | 秘密 | 即 Private Key,一个 64 位十六进制值,必须妥善保密 |
| Public key (hex) | 公开 | 公钥的十六进制表示,可由秘密信息推导 |
| Account ID | 公开 | 账户标识,通常与公钥十六进制一致 |
| SS58 Address | 公开 | 面向特定网络的地址表示(见下文) |
其中助记词与秘密种子是仅有的两份"秘密"信息,其余所有字段都可以从它们推导出来。公钥与Account ID独立于具体网络;而SS58 Address(即公开地址)则是公钥针对某一特定网络的编码表示——同一个种子在不同网络中对应不同的 SS58 地址。例如对上述种子:
- Polkadot:
16m4J167Mptt8UXL8aGSAi7U2FnPpPxZHPrCgMG9KJzVoFqM - Kusama:
JLNozAv8QeLSbLFwe2UvWeKKE4yvmDbfGxTuiYkF2BUMx4M
SS58 地址格式是 Substrate 生态统一的账户地址编码规范(含前缀、校验和等),不同网络通过不同的地址前缀区分。
JSON 输出:面向自动化
默认的文本输出适合人读,而脚本自动化场景则推荐 JSON 输出:
subkey generate --output-type json输出:
{ "accountId": "0xfec70cfbf1977c6965b5af10a4534a6a35d548eb14580594d0bc543286892515", "publicKey": "0xfec70cfbf1977c6965b5af10a4534a6a35d548eb14580594d0bc543286892515", "secretPhrase": "hotel forest jar hover kite book view eight stuff angle legend defense", "secretSeed": "0xa05c75731970cc7868a2fb7cb577353cd5b31f62dccced92c441acd8fee0c92d", "ss58Address": "5Hpm9fq3W3dQgwWpAwDS2ZHKAdnk86QRCu7iX4GnmDxycrte" }配合jq可以只提取某个字段,例如只取秘密种子:
subkey generate --output-type json | jq -r .secretSeed输出:
0xa05c75731970cc7868a2fb7cb577353cd5b31f62dccced92c441acd8fee0c92d附加用户自定义密码
generate支持在种子之外再追加一段用户自定义的密码(password),它会被混入密钥派生过程:
subkey generate --password extra_secret输出:
Secret phrase `soup lyrics media market way crouch elevator put moon useful question wide` is account: Secret seed: 0xe7cfd179d6537a676cb94bac3b5c5c9cb1550e846ac4541040d077dfbac2e7fd Public key (hex): 0xf6a233c3e1de1a2ae0486100b460b3ce3d7231ddfe9dadabbd35ab968c70905d Account ID: 0xf6a233c3e1de1a2ae0486100b460b3ce3d7231ddfe9dadabbd35ab968c70905d SS58 Address: 5He5pZpc7AJ8evPuab37vJF6KkFDqq9uDq2WXh877Qw6iaVC设置密码后,仅凭助记词无法恢复原账户。例如直接用助记词检查:
subkey inspect "soup lyrics media market way crouch elevator put moon useful question wide"恢复出的是5Fe4sqj2K4fRuzEGvToi4KATqZfiDU7TqynjXG6PZE2dxwyh,而不是预期的5He5pZpc7AJ8evPuab37vJF6KkFDqq9uDq2WXh877Qw6iaVC。只有同时提供密码才能完整恢复:
subkey inspect --password extra_secret "soup lyrics media market way crouch elevator put moon useful question wide"这次输出才会正确地回到5He5pZpc7AJ8evPuab37vJF6KkFDqq9uDq2WXh877Qw6iaVC。这意味着密码成为恢复账户的"第二个秘密因子"——务必把它与助记词分开妥善保存。
密钥恢复与检查:subkey inspect
如果你手头拥有关于某个密钥的部分信息,inspect子命令可以帮助你补全并展示它的完整信息。
从助记词或种子恢复(拥有秘密信息时)
subkey inspect < mnemonic | seed >例如传入秘密种子:
subkey inspect 0xa05c75731970cc7868a2fb7cb577353cd5b31f62dccced92c441acd8fee0c92d输出:
Secret Key URI `0xa05c75731970cc7868a2fb7cb577353cd5b31f62dccced92c441acd8fee0c92d` is account: Secret seed: 0xa05c75731970cc7868a2fb7cb577353cd5b31f62dccced92c441acd8fee0c92d Public key (hex): 0xfec70cfbf1977c6965b5af10a4534a6a35d548eb14580594d0bc543286892515 Account ID: 0xfec70cfbf1977c6965b5af10a4534a6a35d548eb14580594d0bc543286892515 SS58 Address: 5Hpm9fq3W3dQgwWpAwDS2ZHKAdnk86QRCu7iX4GnmDxycrte仅凭公钥信息检查(无秘密信息时)
如果只有公开数据(公钥或地址),同样可以检查,但只会得到公开字段的子集:
subkey inspect --public < pubkey | address >两条使用注意:
- 助记词 → 种子是单向的:从助记词可以恢复出秘密种子,反之从种子无法还原出助记词;
- 公开信息不可反推秘密:出于显然的原因,仅传入公钥或地址时,
inspect永远无法恢复出任何秘密信息。
消息签名与验证
使用私钥签名
subkey 允许用私钥对消息签名,任何人都可以用你的公钥验证签名:
echo -n <msg> | subkey sign --suri <seed|mnemonic>其中--suri指定签名所用的密钥来源(秘密种子或助记词)。示例:
MESSAGE=hello SURI=0xa05c75731970cc7868a2fb7cb577353cd5b31f62dccced92c441acd8fee0c92d echo -n $MESSAGE | subkey sign --suri $SURI输出(十六进制签名):
9201af3788ad4f986b800853c79da47155f2e08fde2070d866be4c27ab060466fea0623dc2b51f4392f4c61f25381a62848dd66c5d8217fae3858e469ebd668c注意:每次执行
sign的输出都会不同,因为签名过程中引入了随机性(如随机 nonce)。每份签名虽然各不相同,但都是有效的。
使用公钥/地址验证签名
给定消息、签名和地址,verify可以判断该消息是否确实由该地址对应私钥的持有者签名:
echo -n <msg> | subkey verify <sig> <address>示例:
MESSAGE=hello URI=0xfec70cfbf1977c6965b5af10a4534a6a35d548eb14580594d0bc543286892515 SIGNATURE=9201af3788ad4f986b800853c79da47155f2e08fde2070d866be4c27ab060466fea0623dc2b51f4392f4c61f25381a62848dd66c5d8217fae3858e469ebd668c echo -n $MESSAGE | subkey verify $SIGNATURE $URI验证成功时输出:
Signature verifies correctly.验证失败(例如签名不匹配、消息被篡改或地址不对应)时输出:
Error: SignatureInvalid这套签名/验签机制基于 Substrate 的加密原语构建,底层同样支撑着对编码交易的签名与验签场景——在 Substrate 系链上,交易签名正是利用同一套私钥派生与签名算法完成的。换句话说,generate产出的私钥既可以用来签名消息,也可以用于签名链上交易。
派生分层确定性(HD)子密钥
subkey 支持通过 SURI(Secret URI)路径派生子密钥。在 SURI 中使用/分隔派生路径,即可从一个根密钥派生出结构化、可复现的子密钥树。仓库中的真实用法出现在节点开发链的注释示例里,bin/node/cli/src/chain_spec.rs 给出了两种典型写法:
// for i in 1 2 3 4 ; do for j in stash controller; do subkey inspect "$secret"/fir/$j/$i; done; done // for i in 1 2 3 4 ; do for j in session; do subkey --ed25519 inspect "$secret"//fir//$j//$i; done; done // generated with secret: subkey inspect "$secret"/fir从这段注释可以看出两个关键用法:
- 路径派生:
subkey inspect "$secret"/fir/$j/$i会在根秘密$secret之后依次追加fir、$j(如 stash/controller/session)、$i等派生路径段,每一段都会派生出一个确定性的子密钥对。这与 BIP32 风格的分层确定性思路一致,非常适合为测试网批量生成"stash / controller / session"三套角色密钥。 - 指定签名算法:
subkey --ed25519 inspect ...用于在默认的 SR25519 算法之外显式选择 ED25519 算法。Substrate 生态主要使用 SR25519(基于 Schnorr 签名,速度快、适合链上验证),但在需要兼容 ED25519 的场景(例如一些已有的签名工具链)时可以切换。
这种派生方式让开发者可以用一个根助记词 + 路径规则管理一整组相关密钥,而不是为每个账户单独保存一份秘密。
虚荣地址生成:subkey vanity
subkey 内置了虚荣地址(vanity address)生成器,可以搜索一个地址中包含指定模式的种子:
subkey vanity --network polkadot --pattern bob其中--network指定目标网络的 SS58 地址格式,--pattern指定希望地址包含的字符串。示例输出:
Generating key containing pattern 'bob' best: 190 == top: 189 Secret Key URI `0x8c9a73097f235b84021a446bc2826a00c690ea0be3e0d81a84931cb4146d6691` is account: Secret seed: 0x8c9a73097f235b84021a446bc2826a00c690ea0be3e0d81a84931cb4146d6691 Public key (hex): 0x1a8b32e95c1f571118ea0b84801264c3c70f823e320d099e5de31b9b1f18f843 Account ID: 0x1a8b32e95c1f571118ea0b84801264c3c70f823e320d099e5de31b9b1f18f843 SS58 Address: 1bobYxBPjZWRPbVo35aSwci1u5Zmq8P6J2jpa4kkudBZMqE于是 Bob 得到了一串以自己名字开头的地址:1**bob**YxBPjZWRPbVo35aSwci1u5Zmq8P6J2jpa4kkudBZMqE。
需要提醒的是,虚荣地址生成本质上是暴力搜索:模式越短越容易命中,模式越长越耗时。例如 3 个字符的bob可以较快搜到,而 5 个字符的alice需要尝试的随机地址数量呈指数级增长,耗时显著加长。在批量搜索或长时间运行时,应根据硬件情况量力而行。
密钥安全最佳实践
仓库 bin/utils/subkey/SECURITY.md 对密钥安全给出了明确的守则,总结如下:
subkey 会生成并展示两份"秘密"信息:
- secret phrase(助记词):一串单词,默认 12 个(也可为 12、15、18、21 或 24 个);
- secret seed(秘密种子):一个大十六进制数值。
私钥面临两类核心风险:
- 丢失:没有做好备份,密钥一旦丢失即永久无法找回;
- 泄露:包括恶意软件、钓鱼、键盘记录器、备份存放于联网且未妥善保护的机器等多种途径。
你必须确保:既不丢失这两份秘密,也不让除你之外的任何人访问到它们。
具体行动准则:
- ☠️绝不在任何情况下向任何人透露助记词或秘密种子——一旦泄露,对方即可动用你的资金、代你发送交易;
- ☠️ 如果有人索要你的助记词或秘密种子,可以确信对方是在试图盗取你的资金;
- ✅SS58 地址本来就是公开信息,可以放心分享,收款或交互只需要你的公开地址;
- ⚠️ 同一把密钥在多条链上复用虽然技术上可行,但通常不建议,除非你有充分的理由并理解其中的风险与弊端;
- 建议先在测试网(如 Westend)上练习,测试网上的代币损失不会带来财务后果,是安全的实验场所。
此外,bin/utils/subkey/README.md 还提醒:若将 subkey 输出保存到文件,务必设置合适的文件权限,并在用完后尽快删除。
获取完整命令列表
本文覆盖了 subkey 的核心高频操作,但并非全部能力。任何时刻都可以通过内建帮助查看完整的命令清单:
subkey --help大多数子命令还提供更细粒度的帮助,例如:
subkey generate --help小结
subkey 是 Substrate 生态密钥管理的标准工具:generate负责产出密码学安全的密钥对(支持 JSON 输出与自定义密码),inspect负责从助记词、种子乃至公钥地址恢复和检查密钥信息,sign/verify提供消息及交易签名验证能力,SURI 路径派生支持按角色批量派生子密钥,vanity可生成含指定模式的地址。官方同时提供cargo install与 Docker 容器两种分发方式,容器镜像由仓库中的 subkey.Dockerfile 构建,以非 root 用户、单二进制入口的方式交付。
无论你是 Substrate 节点运营者、平行链开发者,还是链上账户的使用者,掌握 subkey 就等于掌握了账户密钥从生成、备份、恢复到使用的完整闭环。请始终牢记:助记词与秘密种子是你的全部资产,离线生成、妥善备份、绝不外泄。
- 区块链
- 开发框架
- 后端
【免费下载链接】substrate
Substrate: The platform for blockchain innovators
相关推荐
Substrate Subkey 实用手册:账户密钥生成、密钥检视、消息签名验签与靓号地址
Substrate Subkey 实用手册:账户密钥生成、密钥检视、消息签名验签与靓号地址 本文基于 Substrate 仓库中 subkey 工具的官方文档(
区块链开发框架后端Gradle 制品签名密钥完全指南:从密钥管理到 GPG 验证与依赖验证实战
Gradle 制品签名密钥完全指南:从密钥管理到 GPG 验证与依赖验证实战 Gradle 官方对自身产出的每一个制品(无论发布到制品仓库还是通过发行版渠道分发
构建工具开发工具Fleet 许可证(License)密钥生成完全指南:ES256 签名的 JWT 密钥原理与实战
Fleet 许可证(License)密钥生成完全指南:ES256 签名的 JWT 密钥原理与实战 Fleet 是开源的设备管理平台(open device ma
后端前端企业应用运维网络安全
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考