PHP 怎么硬件绑定

wen PHP项目 1

本文目录导读:

PHP 怎么硬件绑定

  1. 常用的硬件识别方案
  2. 生成硬件指纹
  3. 完整的授权验证系统
  4. 使用示例
  5. 增强安全性建议
  6. 注意事项
  7. 最佳实践

在 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);
}

注意事项

  1. Linux 环境下可能需要 root 权限 来执行某些系统命令。
  2. 虚拟机中硬件信息可能会变化,建议在虚拟化环境中禁用某些识别。
  3. MAC 地址可伪造,建议结合多种硬件信息。
  4. 性能考虑:获取硬件信息可能比较慢,建议缓存结果。
  5. 跨平台兼容性:需要测试不同操作系统。
  6. 安全性:注意保护密钥和授权数据,避免被读取或修改。

最佳实践

  1. 结合在线验证和离线验证
  2. 使用时间戳防止回滚
  3. 定期更新硬件指纹
  4. 提供授权异常处理机制
  5. 考虑用户隐私,只获取必要信息
  6. 提供人工审核支持

这样实现后,你的 PHP 应用就能有效地绑定硬件,防止未授权使用。

抱歉,评论功能暂时关闭!