如何生成助记词?

解读

在国内 Rust 岗位面试中,“助记词”通常不是自然语言提示,而是符合 BIP-39 标准的 12/15/18/21/24 个英文单词序列,用于确定性钱包的种子熵备份。面试官想考察的是:

  1. 你是否理解熵→助记词→种子→私钥的完整派生链路;
  2. 能否用 Rust 安全、零依赖泄露地实现该流程;
  3. 是否掌握国密合规与内存安全的边界(国内项目常要求 SM2/SM3 与国密随机源)。
    回答时务必强调不引入第三方热钱包代码、不打印日志、清零内存,并给出可审计的 Cargo 特征开关

知识点

  1. BIP-39:熵长度与校验位关系(128+4、160+5…256+8)。
  2. Rust 密码学库选型:tiny-bip39(纯 Rust,no_std 支持) vs bip39(带零化)。
  3. 随机源:
    • std 环境用 rand::rngs::OsRng(封装了 Linux getrandom 系统调用,国密验收认可);
    • no_std 环境需对接国密随机数芯片TrustZone TA
  4. 内存安全:
    • 使用 zeroize::Zeroize 在 Drop 时清零熵数组;
    • 禁止 format! 打印助记词
    • 使用 secrecy::{Secret, ExposeSecret} 封装敏感数据。
  5. 国际化:国内硬件钱包常要求简体中文词表,需验证GB 18030 编码无乱码与英文索引一一对应
  6. 单元测试:必须包含已知向量测试(BIP-39 官方测试向量)与国密随机源单测gmssl-rand crate 的 mock_rand feature)。

答案

use bip39::{Mnemonic, Language, MnemonicType};
use rand::rngs::OsRng;
use zeroize::Zeroize;

/// 生成符合国密验收的 24 词助记词
/// 返回 Mnemonic,调用者负责不落盘、不打印
pub fn generate_mnemonic() -> Mnemonic {
    // 256-bit 熵,对应 24 词
    let mut entropy = [0u8; 32];
    OsRng.fill_bytes(&mut entropy);
    let mnemonic = Mnemonic::from_entropy(&entropy, Language::English)
        .expect("entropy length valid");
    entropy.zeroize();          // 立即清零熵
    mnemonic
}

/// 使用示例(仅演示,生产代码禁止 `println!`)
#[cfg(test)]
mod tests {
    use super::*;
    #[test]
    fn test_vector_24() {
        let m = generate_mnemonic();
        assert_eq!(m.word_count(), 24);
        // 验证 checksum 通过
        assert!(Mnemonic::from_phrase(m.phrase(), Language::English).is_ok());
    }
}

关键细节

  • Cargo.toml 仅启用必需 feature:bip39 = { version = "2", default-features = false, features = ["std", "zeroize"] },避免拉入无关加密原语。
  • 若对接国密随机源,替换 OsRnggmssl_rand::GmRng,并在 build.rs 中检测 /dev/hwrng 节点是否存在,缺失时编译失败,满足等保 3 级要求。
  • 交付前跑** Miri + Sanitizer** 确保无内存泄漏,审计报告需包含 zeroize 汇编级清零证据。

拓展思考

  1. 如果面试官追问“如何防止侧信道通过功耗分析拿到助记词?”
    答:在裸机环境关闭 core::hint::black_box 优化,使用 volatile_write 逐字节拷贝,并开启时钟抖动;Rust 侧用 inline(never) 拆分查表过程,避免词表访问地址与熵位一一对应
  2. 若需求改为分层确定性钱包(BIP-44),下一步用 slip10 crate 派生 m/44'/60'/0'/0/0国密场景下把 hmac-sha512 替换为 hmac-sm3,需自实现 Slip10Sm3 trait 并提交密码学评估报告
  3. 国内监管要求助记词不得出境,需在 TEE 内生成并加密存储于 SE 芯片。Rust 可借助 optee-teec crate 调用 TrustZone,助记词短语仅存在于安全世界内存,Rich OS 侧仅拿到加密 blob,满足《区块链密码应用指南》第 7.2 条。