180 条记录
15 私有链接
15 私有链接
注册机
//Cargo.toml
[dependencies]
rsa = "0.9.7"
rand = "0.8.5"
sha2 = "0.10.8"
pkcs1 = { version = "0.7.5", features = ["pem"] }
hex = "0.4.3"
// main.rs
use rand::rngs::OsRng;
use rsa::pkcs1::{
DecodeRsaPrivateKey, DecodeRsaPublicKey, EncodeRsaPrivateKey, EncodeRsaPublicKey, LineEnding,
};
use rsa::signature::SignatureEncoding;
use rsa::signature::{Signer, Verifier};
use rsa::{pkcs1v15::SigningKey, pkcs1v15::VerifyingKey, RsaPrivateKey, RsaPublicKey};
use sha2::{Digest, Sha256};
use std::fs::File;
use std::io::{self, Read, Write};
/// 生成 RSA 公私钥并保存到文件
fn generate_keys() -> io::Result<()> {
let mut rng = OsRng;
// 生成 2048 位私钥
let private_key = RsaPrivateKey::new(&mut rng, 2048).expect("密钥生成失败");
let public_key = RsaPublicKey::from(&private_key);
// 保存私钥到文件
let private_key_pem = private_key
.to_pkcs1_pem(LineEnding::LF)
.expect("私钥编码失败: 无法将私钥编码为 PKCS#1 格式");
let mut private_key_file = File::create("private_key.pem")?;
private_key_file.write_all(private_key_pem.as_bytes())?;
// 保存公钥到文件
let public_key_pem = public_key
.to_pkcs1_pem(LineEnding::LF)
.expect("公钥编码失败: 无法将公钥编码为 PKCS#1 格式");
let mut public_key_file = File::create("public_key.pem")?;
public_key_file.write_all(public_key_pem.as_bytes())?;
println!("密钥已生成并保存到 'private_key.pem' 和 'public_key.pem' 文件中。");
Ok(())
}
/// 根据机器码生成授权文件
fn generate_license() -> io::Result<()> {
// 让用户输入机器码
println!("请输入机器码:");
let mut machine_code = String::new();
io::stdin().read_line(&mut machine_code)?;
let machine_code = machine_code.trim();
if machine_code.is_empty() || !machine_code.chars().all(|c| c.is_ascii_alphanumeric()) {
return Err(io::Error::new(
io::ErrorKind::InvalidInput,
"机器码格式无效: 应仅包含字母和数字",
));
}
// 从文件中读取私钥
let private_key_pem = std::fs::read_to_string("private_key.pem")?;
let private_key = RsaPrivateKey::from_pkcs1_pem(&private_key_pem).expect("无效的私钥");
// 计算机器码的哈希
let mut hasher = Sha256::new();
hasher.update(machine_code);
let hashed_machine_code = hasher.finalize();
// 使用私钥对哈希签名
let signing_key = SigningKey::<Sha256>::new_unprefixed(private_key);
let signature = signing_key.sign(&hashed_machine_code);
// 将机器码和签名保存到授权文件
let license_filename = format!("{}_license.dat", machine_code);
let mut license_file = File::create(&license_filename)?;
if license_file.metadata().is_err() {
return Err(io::Error::new(io::ErrorKind::Other, "无法创建授权文件"));
}
writeln!(license_file, "{}", machine_code)?; // 保存机器码并换行
writeln!(license_file, "{}", hex::encode(signature.to_bytes()))?; // 保存签名为十六进制字符串
println!("授权文件 '{}' 已创建。", license_filename);
Ok(())
}
/// 批量生成授权文件
fn batch_generate_licenses() -> io::Result<()> {
// 读取 licenses.txt 文件
let mut file = match File::open("licenses.txt") {
Ok(f) => f,
Err(_) => {
println!("未找到 'licenses.txt' 文件,请创建该文件,每行输入一个机器码。");
return Err(io::Error::new(
io::ErrorKind::NotFound,
"缺少 licenses.txt 文件",
));
}
};
let mut content = String::new();
file.read_to_string(&mut content)?;
// 逐行处理机器码
for machine_code in content.lines() {
let machine_code = machine_code.trim();
if machine_code.is_empty() || !machine_code.chars().all(|c| c.is_ascii_alphanumeric()) {
eprintln!("跳过无效机器码: {}", machine_code);
continue;
}
// 从文件中读取私钥
let private_key_pem = std::fs::read_to_string("private_key.pem")?;
let private_key = RsaPrivateKey::from_pkcs1_pem(&private_key_pem).expect("无效的私钥");
// 计算机器码的哈希
let mut hasher = Sha256::new();
hasher.update(machine_code);
let hashed_machine_code = hasher.finalize();
// 使用私钥对哈希签名
let signing_key = SigningKey::<Sha256>::new_unprefixed(private_key);
let signature = signing_key.sign(&hashed_machine_code);
// 将机器码和签名保存到授权文件
let license_filename = format!("{}_license.dat", machine_code);
let mut license_file = File::create(&license_filename)?;
if license_file.metadata().is_err() {
eprintln!("无法创建授权文件: {}", license_filename);
continue;
}
writeln!(license_file, "{}", machine_code)?; // 保存机器码并换行
writeln!(license_file, "{}", hex::encode(signature.to_bytes()))?; // 保存签名为十六进制字符串
println!("授权文件 '{}' 已创建。", license_filename);
}
Ok(())
}
/// 使用公钥验证授权文件
fn verify_license() -> io::Result<()> {
// 让用户输入机器码
println!("请输入机器码:");
let mut machine_code = String::new();
io::stdin().read_line(&mut machine_code)?;
let machine_code = machine_code.trim();
if machine_code.is_empty() || !machine_code.chars().all(|c| c.is_ascii_alphanumeric()) {
return Err(io::Error::new(
io::ErrorKind::InvalidInput,
"机器码格式无效: 应仅包含字母和数字",
));
}
let license_filename = format!("{}_license.dat", machine_code);
// 检查授权文件是否存在
if !std::path::Path::new(&license_filename).exists() {
return Err(io::Error::new(io::ErrorKind::NotFound, "授权文件不存在"));
}
// 从文件中读取公钥
let public_key_pem = std::fs::read_to_string("public_key.pem")?;
let public_key = RsaPublicKey::from_pkcs1_pem(&public_key_pem)
.map_err(|_| io::Error::new(io::ErrorKind::InvalidData, "公钥读取失败或格式无效"))?;
// 读取授权文件
let mut license_file = File::open(&license_filename)?;
let mut content = String::new();
license_file.read_to_string(&mut content)?;
// 按行解析授权文件内容
let mut lines = content.lines();
let machine_code_in_file = lines
.next()
.ok_or_else(|| io::Error::new(io::ErrorKind::InvalidData, "授权文件中缺少机器码"))?;
let signature_hex = lines
.next()
.ok_or_else(|| io::Error::new(io::ErrorKind::InvalidData, "授权文件中缺少签名"))?;
let signature_bytes = hex::decode(signature_hex)
.map_err(|_| io::Error::new(io::ErrorKind::InvalidData, "签名格式无效"))?;
// 验证机器码匹配
if machine_code != machine_code_in_file {
return Err(io::Error::new(io::ErrorKind::InvalidData, "机器码不匹配"));
}
// 计算机器码的哈希
let mut hasher = Sha256::new();
hasher.update(machine_code);
let hashed_machine_code = hasher.finalize();
// 验证签名
let verifying_key = VerifyingKey::<Sha256>::new_unprefixed(public_key);
let signature = rsa::pkcs1v15::Signature::try_from(signature_bytes.as_slice())
.map_err(|_| io::Error::new(io::ErrorKind::InvalidData, "签名无效"))?;
verifying_key
.verify(&hashed_machine_code, &signature)
.map_err(|_| io::Error::new(io::ErrorKind::InvalidData, "授权验证失败"))?;
println!("授权验证成功!");
Ok(())
}
fn main() {
loop {
println!("请选择功能:");
println!("1. 生成 RSA 密钥");
println!("2. 为机器码生成授权文件");
println!("3. 批量生成授权文件");
println!("4. 验证授权文件");
println!("5. 退出");
let mut choice = String::new();
io::stdin().read_line(&mut choice).expect("读取输入失败");
let choice = choice.trim();
match choice {
"1" => {
if let Err(e) = generate_keys() {
eprintln!("密钥生成失败:{}", e);
}
}
"2" => {
if let Err(e) = generate_license() {
eprintln!("授权文件生成失败:{}", e);
}
}
"3" => {
if let Err(e) = batch_generate_licenses() {
eprintln!("批量授权文件生成失败:{}", e);
}
}
"4" => {
if let Err(e) = verify_license() {
eprintln!("授权验证失败:{}", e);
}
}
"5" => {
println!("退出程序。");
break;
}
_ => println!("无效的选项,请重新选择。"),
}
}
}
机器码
//Cargo.toml
winapi = { version = "0.3.9", features = ["fileapi", "sysinfoapi", "winnt"] }
sha2 = "0.10.8"
rsa = "0.9.7"
reqwest = { version = "0.12.12", features = ["blocking"] }
hex = "0.4.3"
cipher = { version = "0.4.4", features = ["block-padding"] }
aes = "0.8.4"
cbc = "0.1.2"
// 模块 register_app.rs
extern crate winapi;
use std::ffi::OsString;
use std::os::windows::ffi::OsStrExt;
use std::process::Command;
use winapi::um::fileapi::GetVolumeInformationW;
use aes::Aes128;
use cipher::{block_padding::Pkcs7, BlockEncryptMut, KeyIvInit};
use sha2::{Digest, Sha256};
use reqwest::blocking::get;
use rsa::pkcs1::DecodeRsaPublicKey;
use rsa::signature::Verifier;
use rsa::{pkcs1v15::VerifyingKey, RsaPublicKey};
use std::path::Path;
use std::{
fs,
io::{self, Read},
};
// 类型定义:AES加密模式
type Aes128CbcEnc = cbc::Encryptor<aes::Aes128>;
/// 更新 public_key 文件
pub fn update_public_key() -> Result<String, io::Error> {
// 远程公钥的URL
let remote_url = "http://dl.r1.cccxx.cc//file/register/public_key.pem";
// 步骤1:尝试从远程URL获取公钥
let public_key = match get(remote_url) {
Ok(response) => {
if response.status().is_success() {
response.text().ok()
} else {
None
}
}
Err(_) => None,
};
// 如果成功且非空,请将其保存到本地文件并返回
if let Some(key) = public_key {
if !key.trim().is_empty() {
fs::write("public_key.pem", &key).map_err(|e| {
io::Error::new(io::ErrorKind::Other, format!("保存公钥失败: {}", e))
})?;
return Ok(key);
}
}
// 步骤2:如果远程获取失败,请检查本地文件
if let Ok(public_key_pem) = fs::read_to_string("public_key.pem") {
if let Ok(_) = RsaPublicKey::from_pkcs1_pem(&public_key_pem) {
return Ok(public_key_pem);
} else {
return Err(io::Error::new(
io::ErrorKind::InvalidData,
"公钥读取失败或格式无效",
));
}
}
// 步骤3:使用内置公钥作为回退
let built_in_public_key = r"-----BEGIN RSA PUBLIC KEY-----
MIIBCgKCAQEAox+Lis9OWXQIPAf9lvQvtRIhiTKZi1wOgv6JBHcKqFFSzCEUVFSE
I+8jOH386HxT7e8UpIuuUqC5wuMKfYwF5Ohn/IaegtPVklRxD0fewK6Uhflcwhmn
FeL+AtPk0FRxqd11SY50t1DOPY1H23RICa9+QuSHZ5aecnRtqjIricDfCC175mKm
NOZu8pXFFxKAYqVtky2BrVtEKmp7qyklSzhdtS88SOuN5foUdEoPppx3WGlUwV8X
6vUcHgYIOcHgYOWMqMqA+yFBjLlIXXDjBr7WvQke2jFlQ2C4M0kcxeyJSpXakIF/
Ot+QM3XQHk8nAoZ4USHqWFNSpFTZ8tr1sQIDAQAB
-----END RSA PUBLIC KEY-----";
// 如果其他选项不起作用,请将内置公钥保存到本地文件
fs::write("public_key.pem", built_in_public_key)
.map_err(|e| io::Error::new(io::ErrorKind::Other, format!("保存内置公钥失败: {}", e)))?;
Ok(built_in_public_key.to_string())
}
/// 验证授权文件
pub fn verify_license() -> Result<(), io::Error> {
// 获取机器码
let machine_code = generate_machine_code();
// 授权文件名
let license_filename = format!("{}_license.dat", machine_code);
// 检查授权文件是否存在
if !Path::new(&license_filename).exists() {
return Err(io::Error::new(io::ErrorKind::NotFound, "授权文件不存在"));
}
// 读取公钥
let public_key_pem = fs::read_to_string("public_key.pem")?;
let public_key = RsaPublicKey::from_pkcs1_pem(&public_key_pem)
.map_err(|_| io::Error::new(io::ErrorKind::InvalidData, "公钥格式无效"))?;
// 读取授权文件
let mut license_file = fs::File::open(&license_filename)?;
let mut content = String::new();
license_file.read_to_string(&mut content)?;
// 按行解析授权文件内容
let mut lines = content.lines();
let machine_code_in_file = lines
.next()
.ok_or_else(|| io::Error::new(io::ErrorKind::InvalidData, "授权文件中缺少机器码"))?;
let signature_hex = lines
.next()
.ok_or_else(|| io::Error::new(io::ErrorKind::InvalidData, "授权文件中缺少签名"))?;
let signature_bytes = hex::decode(signature_hex)
.map_err(|_| io::Error::new(io::ErrorKind::InvalidData, "签名格式无效"))?;
// 验证机器码匹配
if machine_code != machine_code_in_file {
return Err(io::Error::new(io::ErrorKind::InvalidData, "机器码不匹配"));
}
// 计算机器码的哈希
let mut hasher = Sha256::new();
hasher.update(machine_code);
let hashed_machine_code = hasher.finalize();
// 验证签名
let verifying_key = VerifyingKey::<Sha256>::new_unprefixed(public_key);
let signature = rsa::pkcs1v15::Signature::try_from(signature_bytes.as_slice())
.map_err(|_| io::Error::new(io::ErrorKind::InvalidData, "签名无效"))?;
verifying_key
.verify(&hashed_machine_code, &signature)
.map_err(|_| io::Error::new(io::ErrorKind::InvalidData, "授权验证失败"))?;
println!("授权验证成功!");
Ok(())
}
// 获取硬盘序列号
fn get_disk_serial() -> Option<String> {
let mut volume_name = [0u16; 1024];
let mut volume_serial_number: u32 = 0;
let mut file_system_name = [0u16; 1024];
let mut file_system_flags: u32 = 0;
let c_drive = "C:\\";
let c_drive_wide: Vec<u16> = OsString::from(c_drive)
.encode_wide()
.chain(std::iter::once(0))
.collect();
unsafe {
let result = GetVolumeInformationW(
c_drive_wide.as_ptr(),
volume_name.as_mut_ptr(),
volume_name.len() as u32,
&mut volume_serial_number,
std::ptr::null_mut(),
&mut file_system_flags,
file_system_name.as_mut_ptr(),
file_system_name.len() as u32,
);
if result != 0 {
Some(format!("{:X}", volume_serial_number))
} else {
None
}
}
}
// 通用 WMIC 获取信息函数
fn get_wmic_info(args: &[&str]) -> Option<String> {
match Command::new("wmic").args(args).output() {
Ok(output) => {
let result = String::from_utf8_lossy(&output.stdout);
let lines: Vec<&str> = result.lines().collect();
if lines.len() > 1 {
Some(lines[1].trim().to_string())
} else {
eprintln!("意外的输出格式: {:?}", result);
None
}
}
Err(e) => {
eprintln!("执行WMIC命令失败: {}", e);
None
}
}
}
// 获取 CPU 信息
fn get_cpu_info() -> Option<String> {
get_wmic_info(&["cpu", "get", "ProcessorId"])
}
// 获取主板序列号
fn get_motherboard_serial() -> Option<String> {
get_wmic_info(&["baseboard", "get", "SerialNumber"])
}
// 获取 BIOS 序列号
fn get_bios_serial() -> Option<String> {
get_wmic_info(&["bios", "get", "SerialNumber"])
}
// 获取 BIOS 制造商
fn get_bios_manufacturer() -> Option<String> {
get_wmic_info(&["bios", "get", "Manufacturer"])
}
// 获取 SMBIOS BIOS 版本
fn get_smbios_bios_version() -> Option<String> {
get_wmic_info(&["bios", "get", "SMBIOSBIOSVersion"])
}
// AES加密
fn aes_encrypt(data: &str, key: &[u8], iv: &[u8]) -> Result<Vec<u8>, Box<dyn std::error::Error>> {
// println!("Key length: {}, IV length: {}", key.len(), iv.len());
if key.len() != 16 || iv.len() != 16 {
return Err("密钥或IV长度无效".into());
}
let cipher: cbc::Encryptor<Aes128> = match Aes128CbcEnc::new_from_slices(key, iv) {
Ok(c) => c,
Err(e) => {
eprintln!("密码初始化失败: {:?}", e);
return Err("AES参数无效".into());
}
};
let mut buffer = data.as_bytes().to_vec();
// println!("Buffer before padding : {:?}", buffer);
let block_size = 16;
let padding_len = block_size - (buffer.len() % block_size);
let padding_len = if padding_len == 0 {
block_size
} else {
padding_len
};
// 填充数据
buffer.extend(vec![padding_len as u8; padding_len]);
// 调整缓冲区长度,确保有足够的空间
let buffer_len = buffer.len();
buffer.resize(buffer_len + block_size, 0); // 预留一个块的空间
// println!("Buffer before encryption: {:?}", buffer);
// println!("Buffer length: {}", buffer.len());
assert_eq!(buffer_len % block_size, 0, "缓冲区长度必须是块大小的倍数");
// 加密
match cipher.encrypt_padded_mut::<Pkcs7>(&mut buffer, buffer_len) {
Ok(ciphertext) => Ok(ciphertext.to_vec()), // 加密成功,返回加密后的缓冲区
Err(e) => {
// 加密失败,打印错误信息
eprintln!("加密过程失败: {:?}", e);
Err("加密失败".into())
}
}
}
// 生成机器码
pub fn generate_machine_code() -> String {
let disk_serial = get_disk_serial().unwrap_or_else(|| "UnknownDisk".to_string());
let cpu_info = get_cpu_info().unwrap_or_else(|| "UnknownCPU".to_string());
let motherboard_serial =
get_motherboard_serial().unwrap_or_else(|| "UnknownMotherboard".to_string());
let bios_serial = get_bios_serial().unwrap_or_else(|| "UnknownBIOSSerial".to_string());
let bios_manufacturer =
get_bios_manufacturer().unwrap_or_else(|| "UnknownManufacturer".to_string());
let smbios_bios_version =
get_smbios_bios_version().unwrap_or_else(|| "UnknownSMBIOSVersion".to_string());
// 打印各个部分的信息
// println!("Disk Serial: {}", disk_serial);
// println!("CPU Info: {}", cpu_info);
// println!("Motherboard Serial: {}", motherboard_serial);
// println!("BIOS Serial: {}", bios_serial);
// println!("BIOS Manufacturer: {}", bios_manufacturer);
// println!("SMBIOS BIOS Version: {}", smbios_bios_version);
// 拼接机器码
let machine_code = format!(
"{}-{}-{}-{}-{}-{}",
disk_serial,
cpu_info,
motherboard_serial,
bios_serial,
bios_manufacturer,
smbios_bios_version
);
// AES加密密钥和IV(需固定长度:16字节)
let key = b"jlZp6FubWOiNo7jG"; // 示例密钥
let iv = b"mOUZhQhMc0MO6Vno"; // 示例IV
// AES加密机器码
let encrypted_code = match aes_encrypt(&machine_code, key, iv) {
Ok(code) => code,
Err(e) => {
eprintln!("加密失败: {}", e);
return "加密错误".to_string(); // 或者返回一个默认值
}
};
// 生成哈希值
let mut hasher = Sha256::new();
hasher.update(&encrypted_code);
let hash_result = hasher.finalize();
// 返回加密后的哈希值
format!("{:X}", hash_result)
}
/// 控制流程主函数
pub fn run() {
// 打印本机机器码
let machine_code = generate_machine_code();
println!("机器码: {}", machine_code);
// 更新公钥
match update_public_key() {
Ok(_) => println!("验证授权……"),
Err(e) => {
eprintln!("初始化授权失败: {}", e);
std::process::exit(1);
}
}
// 验证授权
if let Err(e) = verify_license() {
eprintln!("授权验证失败: {},程序退出", e);
eprintln!("请访问: xxx.com 获取更多消息");
std::process::exit(0);
}
println!("启动程序……");
}
//main.rs
mod register_app;
use register_app::run;
fn main() {
run();
println!("Hello, world!");
}