Files
AVM360/tools/cpu_id.py

409 lines
13 KiB
Python
Raw Normal View History

2026-04-01 14:11:47 +08:00
# client.py - RK3588板端激活程序永久有效
import os
import sys
import json
import hashlib
import hmac
import requests
import subprocess
import time
import logging
import argparse
from datetime import datetime
# 配置日志
logging.basicConfig(
level=logging.INFO,
format='%(asctime)s - %(levelname)s - %(message)s'
)
logger = logging.getLogger(__name__)
# 配置
CONFIG = {
'SERVER_URL': 'http://129.211.170.245:5000/', # 修改为实际服务器地址
'KEY_FILE': '/etc/device.key', # 密钥文件存储路径
'KEY_BACKUP_FILE': '/etc/device.key.bak', # 密钥备份文件
'CHIP_ID_SOURCES': [
'/sys/devices/soc0/serial_number',
'/sys/devices/platform/ff650000.serial/serial0',
'/proc/cpuinfo'
],
'ACTIVATE_URL': '/activate',
'VERIFY_URL': '/verify',
'ACTIVATE_RETRY_COUNT': 3,
'SECRET_KEY': '69588cc5e1b701942cda09b33de5a95c02471f3aaaf610d80aaf5681f4b166e4' # 必须和服务端一致
}
def get_chip_id():
"""
获取RK3588芯片ID增强版
"""
# 方法1: 从多个系统文件读取
for source in CONFIG['CHIP_ID_SOURCES']:
try:
if os.path.exists(source):
with open(source, 'r') as f:
content = f.read().strip()
# 处理cpuinfo的特殊格式
if source == '/proc/cpuinfo':
for line in content.split('\n'):
if 'Serial' in line:
chip_id = line.split(':')[1].strip()
if chip_id:
logger.info(f"{source}获取芯片ID: {chip_id}")
return chip_id
else:
if content:
logger.info(f"{source}获取芯片ID: {content}")
return content
except Exception as e:
logger.warning(f"读取{source}失败: {e}")
# 方法2: 使用dmidecode命令
try:
result = subprocess.run(
['dmidecode', '-s', 'system-serial-number'],
capture_output=True,
text=True,
timeout=5
)
if result.returncode == 0 and result.stdout.strip():
chip_id = result.stdout.strip()
logger.info(f"从dmidecode获取芯片ID: {chip_id}")
return chip_id
except Exception as e:
logger.warning(f"执行dmidecode失败: {e}")
# 方法3: 读取MAC地址
try:
import uuid
mac = uuid.UUID(int=uuid.getnode()).hex[-12:]
chip_id = f"MAC-{mac}"
logger.warning(f"使用MAC地址生成ID: {chip_id}")
return chip_id
except Exception as e:
logger.error(f"无法获取任何标识: {e}")
return None
def verify_key_signature(chip_id, key_data):
"""
验证密钥签名永久有效
"""
try:
# 构建待签名数据
data_to_sign = f"{chip_id}|{key_data['activation_id']}|{key_data['activate_time']}"
# 计算期望的签名
expected_signature = hmac.new(
CONFIG['SECRET_KEY'].encode('utf-8'),
data_to_sign.encode('utf-8'),
hashlib.sha256
).hexdigest()
# 比对签名
if key_data['signature'] != expected_signature:
logger.error("密钥签名验证失败")
return False, "密钥签名无效"
logger.info("密钥签名验证通过")
return True, "签名验证通过"
except Exception as e:
logger.error(f"签名验证异常: {e}")
return False, f"验证异常: {str(e)}"
def save_key_file(key_data):
"""
保存密钥文件到本地永久有效
"""
try:
# 确保目录存在
key_dir = os.path.dirname(CONFIG['KEY_FILE'])
if key_dir and not os.path.exists(key_dir):
os.makedirs(key_dir, exist_ok=True)
# 如果已有密钥文件,先备份
if os.path.exists(CONFIG['KEY_FILE']):
import shutil
shutil.copy2(CONFIG['KEY_FILE'], CONFIG['KEY_BACKUP_FILE'])
logger.info(f"已备份旧密钥文件到: {CONFIG['KEY_BACKUP_FILE']}")
# 保存新密钥文件
with open(CONFIG['KEY_FILE'], 'w') as f:
json.dump(key_data, f, indent=2)
# 设置文件权限为只读
os.chmod(CONFIG['KEY_FILE'], 0o600)
logger.info(f"密钥文件已保存: {CONFIG['KEY_FILE']}")
return True
except Exception as e:
logger.error(f"保存密钥文件失败: {e}")
return False
def load_key_file():
"""
加载本地密钥文件
"""
try:
# 尝试加载主密钥文件
if os.path.exists(CONFIG['KEY_FILE']):
with open(CONFIG['KEY_FILE'], 'r') as f:
key_data = json.load(f)
logger.info("密钥文件加载成功")
return key_data
# 尝试加载备份密钥文件
if os.path.exists(CONFIG['KEY_BACKUP_FILE']):
logger.warning("主密钥文件不存在,尝试加载备份")
with open(CONFIG['KEY_BACKUP_FILE'], 'r') as f:
key_data = json.load(f)
logger.info("备份密钥文件加载成功")
return key_data
logger.warning("密钥文件不存在")
return None
except Exception as e:
logger.error(f"加载密钥文件失败: {e}")
return None
def verify_local_key(chip_id):
"""
本地验证密钥永久有效无过期检查
"""
# 加载密钥文件
key_data = load_key_file()
if not key_data:
return False, "密钥文件不存在"
# 验证芯片ID是否匹配
if key_data.get('chip_id') != chip_id:
logger.error(f"芯片ID不匹配: 期望 {key_data.get('chip_id')}, 实际 {chip_id}")
return False, "芯片ID不匹配"
# 验证签名
valid, message = verify_key_signature(chip_id, key_data)
if not valid:
return False, message
# 验证通过
logger.info(f"永久激活验证通过!")
logger.info(f"激活时间: {key_data['activate_time']}")
logger.info(f"激活ID: {key_data['activation_id']}")
return True, "验证通过(永久有效)"
def activate_device(chip_id):
"""
联网激活设备永久激活
"""
url = f"{CONFIG['SERVER_URL']}{CONFIG['ACTIVATE_URL']}"
payload = {'chip_id': chip_id}
for attempt in range(CONFIG['ACTIVATE_RETRY_COUNT']):
try:
logger.info(f"正在激活设备 (尝试 {attempt + 1}/{CONFIG['ACTIVATE_RETRY_COUNT']})...")
response = requests.post(
url,
json=payload,
timeout=10,
headers={'Content-Type': 'application/json'}
)
if response.status_code == 200:
data = response.json()
if data.get('code') == 200:
# 保存密钥文件
key_data = data['data']
if save_key_file(key_data):
logger.info("设备永久激活成功!")
return True
else:
logger.error("保存密钥文件失败")
else:
logger.error(f"激活失败: {data.get('message')}")
else:
logger.error(f"HTTP错误: {response.status_code}")
except requests.exceptions.RequestException as e:
logger.error(f"网络错误: {e}")
except Exception as e:
logger.error(f"激活过程中发生错误: {e}")
if attempt < CONFIG['ACTIVATE_RETRY_COUNT'] - 1:
wait_time = 2 ** attempt
logger.info(f"等待 {wait_time} 秒后重试...")
time.sleep(wait_time)
return False
def create_emergency_key(chip_id):
"""
创建应急密钥当无法联网时使用需人工授权
警告此功能仅用于紧急情况
"""
import secrets
logger.warning("正在创建应急密钥...")
# 生成应急密钥数据
emergency_key = {
'chip_id': chip_id,
'activation_id': f"EMERGENCY-{secrets.token_hex(8)}",
'activate_time': datetime.now().strftime('%Y-%m-%d %H:%M:%S'),
'signature': 'EMERGENCY-MODE', # 应急模式签名
'permanent': True,
'emergency': True,
'version': '1.0'
}
# 保存应急密钥
if save_key_file(emergency_key):
logger.warning("应急密钥已创建!请确保这是授权操作!")
return True
return False
def main():
"""
主函数程序启动验证永久有效
"""
parser = argparse.ArgumentParser(description='设备永久激活和验证程序')
parser.add_argument('--force-activate', action='store_true', help='强制重新激活')
parser.add_argument('--check-only', action='store_true', help='仅检查验证状态')
parser.add_argument('--emergency', action='store_true', help='创建应急密钥(仅限授权使用)')
parser.add_argument('--show-info', action='store_true', help='显示激活信息')
args = parser.parse_args()
# 获取芯片ID
chip_id = get_chip_id()
if not chip_id:
logger.error("无法获取芯片ID")
sys.exit(1)
logger.info(f"芯片ID: {chip_id}")
# 应急模式
if args.emergency:
if create_emergency_key(chip_id):
logger.info("应急密钥创建成功")
sys.exit(0)
else:
logger.error("应急密钥创建失败")
sys.exit(1)
# 显示激活信息
if args.show_info:
key_data = load_key_file()
if key_data:
print("\n" + "="*50)
print("设备激活信息")
print("="*50)
print(f"芯片ID: {key_data.get('chip_id')}")
print(f"激活时间: {key_data.get('activate_time')}")
print(f"激活ID: {key_data.get('activation_id')}")
print(f"激活类型: {'永久有效' if key_data.get('permanent') else '临时'}")
if key_data.get('emergency'):
print("警告: 应急模式激活")
print("="*50)
else:
print("设备未激活")
sys.exit(0)
# 检查是否需要激活
need_activate = args.force_activate
if not need_activate:
# 尝试本地验证
valid, message = verify_local_key(chip_id)
if valid:
logger.info(f"✅ 验证成功: {message}")
if not args.check_only:
logger.info("验证通过,启动主程序...")
# 在这里调用你的主程序
# subprocess.run(['python3', 'your_main_program.py'])
sys.exit(0)
else:
logger.warning(f"❌ 本地验证失败: {message}")
need_activate = True
# 需要联网激活
if need_activate:
logger.info("开始联网永久激活...")
if activate_device(chip_id):
# 激活后再次验证
valid, message = verify_local_key(chip_id)
if valid:
logger.info(f"✅ 激活验证成功: {message}")
logger.info("设备已永久激活,无需再次联网!")
if not args.check_only:
logger.info("激活完成,启动主程序...")
# subprocess.run(['python3', 'your_main_program.py'])
sys.exit(0)
else:
logger.error(f"❌ 激活后验证失败: {message}")
sys.exit(1)
else:
logger.error("设备激活失败,请检查网络连接")
sys.exit(1)
def install_service():
"""
安装为系统服务
"""
service_content = """[Unit]
Description=Device Permanent Activation Check Service
After=network.target
[Service]
Type=oneshot
ExecStart=/usr/bin/python3 /opt/device_activation/client.py --check-only
RemainAfterExit=yes
[Install]
WantedBy=multi-user.target
"""
service_file = '/etc/systemd/system/device-activation.service'
try:
# 复制程序到系统目录
script_dir = '/opt/device_activation'
os.makedirs(script_dir, exist_ok=True)
import shutil
shutil.copy2(__file__, os.path.join(script_dir, 'client.py'))
os.chmod(os.path.join(script_dir, 'client.py'), 0o755)
# 创建服务文件
with open(service_file, 'w') as f:
f.write(service_content)
os.chmod(service_file, 0o644)
logger.info(f"服务文件已创建: {service_file}")
logger.info("请执行以下命令启用服务:")
logger.info("sudo systemctl daemon-reload")
logger.info("sudo systemctl enable device-activation.service")
logger.info("sudo systemctl start device-activation.service")
except Exception as e:
logger.error(f"安装服务失败: {e}")
if __name__ == '__main__':
if len(sys.argv) > 1 and sys.argv[1] == 'install-service':
install_service()
else:
main()