Rust离线激活VIP功能实现笔记

学习笔记作者:admin日期:2025-09-02点击:1

摘要:本文详细介绍了如何在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 签名方案,确保安全性、离线验证和防伪造。

上一篇      下一篇