PHP代码安全与授权咨询:基于域名/IP等生成License及WHMCS方案
作为一个做过PHP商业软件授权的开发者,我来分享一套落地性很强的方案,刚好覆盖你要的域名/IP/localkey/过期日期校验,还有WHMCS自动对接的方法。
核心思路:授权证书的本质
授权证书其实就是个加密的身份凭证——把用户的服务器信息(域名、IP、localkey)和过期日期打包,用你的私钥加密成一串字符串。用户的软件运行时,用你提供的公钥解密,然后逐一比对当前服务器的真实信息,所有校验通过才能正常运行。
一、具体实现步骤
1. 先搞定加密/解密的密钥对
用PHP自带的openssl生成非对称密钥对(私钥自己存好,绝对不能泄露;公钥可以打包给用户):
# 生成私钥(密码可选,记得保存好) openssl genrsa -out private.key 2048 # 生成公钥 openssl rsa -in private.key -pubout -out public.key
2. 你的授权证书生成工具(仅你使用)
做一个只有你能访问的后台页面,输入客户的服务器信息,生成加密的授权证书:
<?php // 加载你的私钥 $privateKey = file_get_contents('/绝对路径/你的private.key'); // 模拟客户提交的信息(实际可以做个表单输入) $domain = 'customer-domain.com'; $serverIp = '123.123.123.123'; $localKey = '客户服务器的唯一标识'; $expireDate = '2025-12-31'; // 组装要加密的授权数据 $certData = json_encode([ 'domain' => $domain, 'server_ip' => $serverIp, 'local_key' => $localKey, 'expire_date' => $expireDate, 'created_at' => time() // 加个生成时间防篡改 ]); // 用私钥加密 openssl_private_encrypt($certData, $encrypted, $privateKey); $certificate = base64_encode($encrypted); // 把这个$certificate发给客户,让他们保存为license.crt放在软件根目录 echo "客户的授权证书:<br>" . $certificate; ?>
3. 用户端的验证逻辑(嵌入你的软件)
在软件的入口文件(比如index.php)最顶部加入验证代码,只有通过校验才能继续运行:
<?php // 加载公钥(可以打包进软件) $publicKey = file_get_contents('./public.key'); // 读取客户上传的授权证书 $certFile = './license.crt'; if (!file_exists($certFile)) { die("请先上传授权证书文件 license.crt"); } // 解密证书 $encrypted = base64_decode(file_get_contents($certFile)); openssl_public_decrypt($encrypted, $decrypted, $publicKey); $certData = json_decode($decrypted, true); // 1. 校验域名 $currentDomain = str_replace('www.', '', $_SERVER['HTTP_HOST']); if (str_replace('www.', '', $certData['domain']) !== $currentDomain) { die("当前域名未授权"); } // 2. 校验服务器IP $currentIp = $_SERVER['SERVER_ADDR']; if ($certData['server_ip'] !== $currentIp) { die("当前服务器IP未授权"); } // 3. 校验LocalKey(服务器唯一标识) $localKeyFile = './local.key'; // 如果是第一次运行,自动生成并保存localkey if (!file_exists($localKeyFile)) { $localKey = md5(uniqid(mt_rand(), true) . $_SERVER['SERVER_NAME']); file_put_contents($localKeyFile, $localKey); } else { $localKey = file_get_contents($localKeyFile); } if ($certData['local_key'] !== $localKey) { die("当前服务器未授权"); } // 4. 校验过期时间 if (strtotime($certData['expire_date']) < time()) { die("授权已过期,请联系管理员续费"); } // 所有校验通过,继续运行软件 ?>
4. 代码加密补充(可选但推荐)
如果怕用户篡改验证逻辑,可以用IONCube、Zend Guard或者免费的PHP Source Guardian把核心代码加密。验证逻辑最好放在加密后的入口文件里,或者做代码混淆处理。
二、WHMCS自动对接方案
如果用WHMCS管理客户订单,可以完全自动化授权生成流程——用户付款后自动生成证书并发邮件,不用手动操作。
1. 核心实现思路
- 在WHMCS后台创建一个“PHP软件授权”产品,添加自定义字段让用户填写域名、服务器IP、LocalKey(或者让用户先运行软件生成LocalKey再填写)。
- 写一个WHMCS钩子,监听
InvoicePaid事件(订单付款成功),自动生成授权证书并发送给客户。
2. 钩子代码示例
把下面的代码放在WHMCS根目录的hooks/文件夹里(比如hooks/license_auto_generate.php):
<?php // 监听订单付款成功事件 add_hook('InvoicePaid', 1, function($vars) { $invoiceId = $vars['invoiceid']; // 获取订单和客户信息 $orderResult = localAPI('GetOrders', ['invoiceid' => $invoiceId]); $order = $orderResult['orders']['order'][0]; $client = localAPI('GetClientsDetails', ['clientid' => $order['userid']]); // 从订单自定义字段里取用户提交的服务器信息 $domain = $order['customfields'][0]['value']; $serverIp = $order['customfields'][1]['value']; $localKey = $order['customfields'][2]['value']; // 计算过期时间(比如产品是1年授权) $expireDate = date('Y-m-d', strtotime('+1 year')); // 生成授权证书(和之前的生成逻辑一致) $privateKey = file_get_contents('/绝对路径/你的private.key'); $certData = json_encode([ 'domain' => $domain, 'server_ip' => $serverIp, 'local_key' => $localKey, 'expire_date' => $expireDate, 'created_at' => time() ]); openssl_private_encrypt($certData, $encrypted, $privateKey); $certificate = base64_encode($encrypted); // 发送邮件给客户 $emailContent = "您好,您的PHP软件授权证书已生成:\n\n{$certificate}\n\n请将此内容保存为 license.crt 文件,上传到软件根目录即可使用。"; localAPI('SendEmail', [ 'id' => $client['userid'], 'subject' => '您的PHP软件授权证书已生成', 'message' => $emailContent ]); }); ?>
3. 优化建议
- 在WHMCS产品的自定义字段里添加提示,告诉用户怎么获取LocalKey(比如让他们运行一次软件,软件会自动生成
local.key文件,把里面的内容复制过来)。 - 可以在WHMCS后台加一个“授权管理”页面,让客户查看授权状态、续费后自动更新过期日期。
三、注意事项
- 私钥一定要存在安全的地方,绝对不能泄露,否则用户可以自己生成授权证书。
- LocalKey的生成要确保唯一性,比如结合服务器的主机名、硬件信息(如果能读取到的话),用固定文件保存的方式最可靠。
- 域名校验可以处理掉www前缀,避免用户因为带不带www导致验证失败。
- 可以加个在线验证的逻辑(比如每天请求你的服务器验证证书有效性),防止用户篡改本地证书,但要考虑用户服务器离线的情况,加个缓存机制。
内容的提问来源于stack exchange,提问作者Bootstrap
相关产品推荐
相关产品推荐

