Rust离线激活VIP功能实现笔记
学习笔记作者:admin日期:2025-09-02点击:108
摘要:本文详细介绍了如何在Rust中实现离线激活VIP功能,包括生成设备唯一ID、使用RSA签名机制进行激活码验证以及编译发布程序的命令。重点在于安全性和稳定性,避免激活码被破解。
一、生成设备唯一ID(机器码)
目标:基于当前设备硬件信息生成一个相对唯一的、稳定的字符串,作为“机器码”。
use std::process::Command;
use sysinfo::{System, SystemExt};
fn get_machine_id() -> String {
    let mut system = System::new_all();
    system.refresh_all();
    let mut parts = Vec::new();
    // 1. 主板序列号(Linux/Windows)
    if cfg!(target_os = "windows") {
        if let Ok(output) = Command::new("wmic")
            .args(&["baseboard", "get", "serialnumber"])
            .output()
        {
            let sn = String::from_utf8_lossy(&output.stdout);
            let sn = sn.lines().nth(1).unwrap_or("").trim();
            if !sn.is_empty() && sn != "null" {
                parts.push(sn.to_string());
            }
        }
    } else if cfg!(target_os = "linux") {
        if let Ok(output) = Command::new("sh")
            .args(&["-c", "sudo dmidecode -s baseboard-serial-number"])
            .output()
        {
            let sn = String::from_utf8_lossy(&output.stdout).trim().to_string();
            if !sn.is_empty() && sn != "Not Specified" {
                parts.push(sn);
            }
        }
    }
    // 2. CPU ID(仅 x86/x86_64 可行)
    if let Some(cpu) = system.cpus().first() {
        parts.push(cpu.brand().to_string());
    }
    // 3. 系统主机名
    if let Ok(hostname) = hostname::get() {
        if let Ok(hostname_str) = hostname_str.into_string() {
            parts.push(hostname_str);
        }
    }
    // 4. MAC 地址(可选,但注意隐私和虚拟机问题)
    for (_name, data) in pnet_datalink::interfaces() {
        if let Some(mac) = data.mac {
            parts.push(mac.to_string());
            break; // 只取第一个
        }
    }
    // 拼接后哈希,避免暴露原始信息
    let combined = parts.join("|");
    use sha2::{Sha256, Digest};
    let mut hasher = Sha256::new();
    hasher.update(combined.as_bytes());
    format!("{:x}", hasher.finalize())
}二、激活机制设计(机器码 + 激活码)
推荐方案:非对称签名(RSA)
原理:
- 你在服务器端用私钥对机器码签名,生成激活码。
- 客户端用内置的公钥验证签名。
- 攻击者无法伪造激活码(没有私钥)。
- 完全离线验证。
生成密钥对(一次)
openssl genpkey -algorithm RSA -out private.pem -pkeyopt rsa_keygen_bits:2048
openssl rsa -pubout -in private.pem -out public.pem服务端:生成激活码
use rsa::{PaddingScheme, PublicKey, RsaPrivateKey, RsaPublicKey};
use sha2::{Sha256, Digest};
use base64;
fn generate_activation_code(private_key_pem: &str, machine_id: &str) -> Result> {
    let mut rng = rand::thread_rng();
    let private_key = RsaPrivateKey::from_pkcs1_pem(private_key_pem)?;
    let hash = Sha256::digest(machine_id.as_bytes());
    let signature = private_key.sign(&mut rng, PaddingScheme::PKCS1v15Sign {
        hash: Some(rsa::Hash::SHA2_256),
    }, &hash)?;
    Ok(base64::encode(&signature))
} 客户端:验证激活码
use rsa::{PublicKey, RsaPublicKey, PaddingScheme};
use sha2::{Sha256, Digest};
use base64;
fn verify_activation_code(public_key_pem: &str, machine_id: &str, activation_code: &str) -> bool {
    let public_key = match RsaPublicKey::from_pkcs1_pem(public_key_pem) {
        Ok(k) => k,
        Err(_) => return false,
    };
    let signature = match base64::decode(activation_code) {
        Ok(sig) => sig,
        Err(_) => return false,
    };
    let hash = Sha256::digest(machine_id.as_bytes());
    public_key.verify(
        PaddingScheme::PKCS1v15Sign {
            hash: Some(rsa::Hash::SHA2_256),
        },
        &hash,
        &signature,
    ).is_ok()
}三、防破解增强建议
| 措施 | 说明 | 
|---|---|
| 代码混淆 | 使用 cargo-tamper 或手动混淆关键函数名 | 
| 检查调试器 | 检测 is_debugger_present() | 
| 时间绑定 | 在签名中加入有效期,如 machine_id|2025-12-31 | 
| 多因子绑定 | 绑定机器码 + 用户名,防止共享 | 
| 定期更新公钥 | 防止私钥泄露后长期失效 | 
四、完整流程
用户安装软件
  ↓
程序生成机器码(如:a1b2c3d4...)
  ↓
用户提交机器码给你
  ↓
你用私钥签名,生成激活码(Base64字符串)
  ↓
用户输入激活码
  ↓
程序用内置公钥验证签名是否匹配当前机器码
  ↓
验证通过 → 启用VIP五、编译发布命令
基本发布编译命令
cargo build --release查看输出文件
ls -lh target/release/进一步减小体积
[profile.release]
opt-level = 'z'      # 最小化体积
lto = true           # 全局优化
codegen-units = 1    # 更慢但更小
panic = 'abort'      # 移除 unwind 支持(可选)
strip = true         # 自动去除调试符号(需 nightly 或 Rust 1.70+)打包发布
mkdir -p release-v1.0.0
cp target/release/myapp release-v1.0.0/
cp README.md release-v1.0.0/
cp LICENSE release-v1.0.0/
tar -czf myapp-linux-x64-v1.0.0.tar.gz release-v1.0.0/六、总结
推荐使用 RSA 签名方案,确保安全性、离线验证和防伪造。