本文目录导读:

在 PHP 中实现硬件绑定(也称为机器码绑定、授权绑定)通常是指将软件授权与特定的硬件特征绑定,防止软件被复制到其他机器上运行。
下面我详细介绍几种实现方式和完整的代码示例。
常用的硬件识别方案
获取网卡 MAC 地址(最常用)
<?php
/**
* 获取网卡MAC地址(Windows/Linux通用)
*/
function getMacAddress() {
// Windows系统
if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') {
$output = [];
exec('getmac /FO CSV /NH', $output);
if (!empty($output)) {
// 解析CSV格式输出
$line = str_replace('"', '', $output[0]);
$parts = explode(',', $line);
return strtoupper($parts[0]);
}
} else {
// Linux系统
$output = [];
exec('ifconfig -a 2>/dev/null || ip link show 2>/dev/null', $output);
$content = implode("\n", $output);
// 匹配MAC地址
preg_match_all('/([0-9A-Fa-f]{2}[:-]){5}[0-9A-Fa-f]{2}/', $content, $matches);
if (!empty($matches[0])) {
// 取第一个非虚拟网卡的MAC(通常eth0或enp*)
return strtoupper($matches[0][0]);
}
}
return 'UNKNOWN';
}
获取 CPU 序列号
<?php
/**
* 获取CPU序列号
*/
function getCpuSerial() {
// Windows系统
if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') {
$output = [];
exec('wmic cpu get ProcessorId', $output);
if (!empty($output)) {
foreach ($output as $line) {
$line = trim($line);
if (!empty($line) && $line != 'ProcessorId') {
return $line;
}
}
}
} else {
// Linux系统
$output = [];
exec('dmidecode -t processor 2>/dev/null | grep ID', $output);
if (!empty($output)) {
// 提取十六进制值并转换为字符串
$id = preg_replace('/[^0-9A-Fa-f]/', '', $output[0]);
return $id;
}
// Linux备用方案
$output = [];
exec('cat /proc/cpuinfo | grep -m1 "Serial"', $output);
if (!empty($output)) {
return trim(explode(':', $output[0])[1]);
}
}
return 'UNKNOWN';
}
获取硬盘序列号
<?php
/**
* 获取硬盘序列号
*/
function getDiskSerial() {
// Windows系统
if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') {
$output = [];
exec('wmic diskdrive get SerialNumber', $output);
if (!empty($output)) {
foreach ($output as $line) {
$line = trim($line);
if (!empty($line) && $line != 'SerialNumber') {
return $line;
}
}
}
} else {
// Linux系统
$output = [];
exec('lsblk -n -o SERIAL 2>/dev/null | head -1', $output);
if (!empty($output) && trim($output[0])) {
return trim($output[0]);
}
}
return 'UNKNOWN';
}
获取主板序列号
<?php
/**
* 获取主板序列号
*/
function getMotherboardSerial() {
// Windows
if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') {
$output = [];
exec('wmic baseboard get SerialNumber', $output);
if (!empty($output)) {
foreach ($output as $line) {
$line = trim($line);
if (!empty($line) && $line != 'SerialNumber') {
return $line;
}
}
}
} else {
// Linux
$output = [];
exec('dmidecode -s baseboard-serial-number 2>/dev/null', $output);
if (!empty($output) && trim($output[0]) && strtolower($output[0]) != 'none') {
return trim($output[0]);
}
}
return 'UNKNOWN';
}
生成硬件指纹
<?php
/**
* 生成唯一的硬件指纹
*/
function generateHardwareFingerprint() {
// 获取各项硬件信息
$mac = getMacAddress();
$cpu = getCpuSerial();
$disk = getDiskSerial();
$board = getMotherboardSerial();
// 组合原始数据
$raw = $mac . '|' . $cpu . '|' . $disk . '|' . $board;
// 创建唯一指纹(使用SHA256)
$fingerprint = hash('sha256', $raw);
return [
'fingerprint' => $fingerprint,
'mac' => $mac,
'cpu' => $cpu,
'disk' => $disk,
'board' => $board
];
}
完整的授权验证系统
<?php
class LicenseManager {
private $licenseFile;
private $licenseKeyFile;
public function __construct($licenseFile = 'license.dat', $licenseKeyFile = 'license.key') {
$this->licenseFile = $licenseFile;
$this->licenseKeyFile = $licenseKeyFile;
}
/**
* 生成授权码(提供给用户)
*/
public function generateLicenseKey($fingerprint, $validDays = 365) {
// 密钥(应保密,可配置)
$secret = 'YOUR_SECRET_KEY';
// 过期时间
$expiry = time() + ($validDays * 86400);
// 创建数据
$data = $fingerprint . '|' . $expiry;
// 生成签名
$signature = hash_hmac('sha256', $data, $secret);
// 编码授权码
$license = base64_encode(json_encode([
'fingerprint' => $fingerprint,
'expiry' => $expiry,
'signature' => $signature
]));
return $license;
}
/**
* 激活授权(保存到本地)
*/
public function activateLicense($licenseKey) {
$data = json_decode(base64_decode($licenseKey), true);
// 验证授权码
if ($this->validateLicenseKey($licenseKey, $data)) {
// 保存授权文件
file_put_contents($this->licenseFile, $licenseKey);
return true;
}
return false;
}
/**
* 验证授权
*/
public function validateLicense() {
// 检查授权文件是否存在
if (!file_exists($this->licenseFile)) {
return ['valid' => false, 'message' => 'License file not found'];
}
// 读取授权文件
$license = file_get_contents($this->licenseFile);
// 解析授权数据
$data = json_decode(base64_decode($license), true);
// 验证授权码
return $this->validateLicenseKey($license, $data);
}
/**
* 验证授权码有效性
*/
private function validateLicenseKey($licenseKey, $data) {
$secret = 'YOUR_SECRET_KEY';
// 检查数据完整性
if (!isset($data['fingerprint']) || !isset($data['expiry']) || !isset($data['signature'])) {
return ['valid' => false, 'message' => 'Invalid license data'];
}
// 验证签名
$expectedSignature = hash_hmac('sha256', $data['fingerprint'] . '|' . $data['expiry'], $secret);
if ($expectedSignature != $data['signature']) {
return ['valid' => false, 'message' => 'Invalid signature'];
}
// 检查过期时间
if ($data['expiry'] < time()) {
return ['valid' => false, 'message' => 'License expired'];
}
// 验证硬件指纹
$currentFingerprint = $this->getCurrentFingerprint();
if ($data['fingerprint'] != $currentFingerprint) {
return ['valid' => false, 'message' => 'Hardware fingerprint mismatch'];
}
// 剩余天数
$remainingDays = ceil(($data['expiry'] - time()) / 86400);
return [
'valid' => true,
'message' => 'Valid license',
'expiry' => $data['expiry'],
'remaining_days' => $remainingDays
];
}
/**
* 获取当前机器指纹
*/
private function getCurrentFingerprint() {
$fingerprint = generateHardwareFingerprint();
return $fingerprint['fingerprint'];
}
}
使用示例
生成授权码(管理员使用)
<?php // 生成机器码(用户提供给你) $userHardwareFingerprint = '用户提供的机器码'; // 创建授权管理对象 $licenseManager = new LicenseManager(); // 生成授权码(有效期为365天) $licenseKey = $licenseManager->generateLicenseKey($userHardwareFingerprint, 365); echo "授权码: " . $licenseKey . PHP_EOL;
激活软件(用户执行)
<?php
$licenseManager = new LicenseManager();
// 用户输入授权码
$userLicense = "从开发者获取的授权码";
// 激活
if ($licenseManager->activateLicense($userLicense)) {
echo "激活成功!" . PHP_EOL;
} else {
echo "激活失败,请检查授权码!" . PHP_EOL;
}
验证授权(程序启动时)
<?php
$licenseManager = new LicenseManager();
$result = $licenseManager->validateLicense();
if ($result['valid']) {
echo "欢迎使用本软件!" . PHP_EOL;
echo "剩余天数: " . $result['remaining_days'] . " 天" . PHP_EOL;
} else {
echo "授权无效: " . $result['message'] . PHP_EOL;
exit(1); // 退出程序
}
增强安全性建议
使用 OpenSSL 加密
// 生成密钥对
$keyPair = generateKeyPair();
function generateKeyPair() {
$config = [
"private_key_bits" => 2048,
"private_key_type" => OPENSSL_KEYTYPE_RSA,
];
$res = openssl_pkey_new($config);
openssl_pkey_export($res, $privateKey);
$details = openssl_pkey_get_details($res);
$publicKey = $details['key'];
return ['private_key' => $privateKey, 'public_key' => $publicKey];
}
使用 OAuth 或 API 验证
// 在线验证
function onlineVerification($licenseKey, $fingerprint) {
$apiUrl = 'https://your-server.com/verify-license';
$data = [
'license_key' => $licenseKey,
'fingerprint' => $fingerprint,
'app_version' => '1.0.0'
];
$options = [
'http' => [
'method' => 'POST',
'header' => "Content-Type: application/x-www-form-urlencoded\r\n",
'content' => http_build_query($data),
'timeout' => 10
]
];
$context = stream_context_create($options);
$result = file_get_contents($apiUrl, false, $context);
return json_decode($result, true);
}
加密授权文件
function encryptLicenseFile($content, $key) {
$iv_length = openssl_cipher_iv_length('aes-256-cbc');
$iv = openssl_random_pseudo_bytes($iv_length);
$encrypted = openssl_encrypt($content, 'aes-256-cbc', $key, 0, $iv);
return base64_encode($iv . '::' . $encrypted);
}
function decryptLicenseFile($encryptedContent, $key) {
$data = explode('::', base64_decode($encryptedContent));
if (count($data) != 2) {
return false;
}
list($iv, $encrypted) = $data;
return openssl_decrypt($encrypted, 'aes-256-cbc', $key, 0, $iv);
}
注意事项
- Linux 环境下可能需要 root 权限 来执行某些系统命令。
- 虚拟机中硬件信息可能会变化,建议在虚拟化环境中禁用某些识别。
- MAC 地址可伪造,建议结合多种硬件信息。
- 性能考虑:获取硬件信息可能比较慢,建议缓存结果。
- 跨平台兼容性:需要测试不同操作系统。
- 安全性:注意保护密钥和授权数据,避免被读取或修改。
最佳实践
- 结合在线验证和离线验证
- 使用时间戳防止回滚
- 定期更新硬件指纹
- 提供授权异常处理机制
- 考虑用户隐私,只获取必要信息
- 提供人工审核支持
这样实现后,你的 PHP 应用就能有效地绑定硬件,防止未授权使用。