如需更完整的 PHP 代码保护与在线加密服务,可访问 https://article.vvxyz.com 了解更多。
PHP 加密授权与 license 校验实现
用户现在需要一篇PHP的授权加密故障相关的技术文章,首先得找个真实的痛点切入,比如之前做SaaS系统的时候, license 被逆向破解了对吧?首先开头要接地气,比如去年我们团队接了个电商SaaS的客户,上线半个月发现核心的订单导出功能被破解了,免费用户也能用,一查是license校验的逻辑被逆向扒了,这个场景很真实。
然后结构要按要求来,首先是背景/常见问题,得说清楚常见的PHP授权校验的坑:比如把license校验逻辑写在明面的PHP里,用简单的base64甚至明文存license,或者校验逻辑太简单,比如只校验个域名,被人改了hosts就过了,还有的把密钥硬编码在代码里,一扒就出来。对,还要提那个故障的具体情况:当时我们用的是简单的对称加密存license,密钥写在配置文件里,被人反编译了PHP代码拿到密钥,自己生成license,损失了小十万的授权费,这个够真实。
接下来是方案对比,这个是重点,不能只讲一个方案。首先得列常见的几种方案,各自的优缺点和适用场景:
第一种:明文/简单编码校验,比如base64_decode就完事,优点是实现简单,性能高,缺点是安全性极差,随便就能改,只适合内部非核心系统,完全不能对外。
第二种:对称加密校验,比如AES加密license信息,优点是实现难度中等,性能也不错,缺点是密钥如果硬编码在代码里,还是会被扒,适合对安全要求中等的内部系统,或者小范围分发的工具。
第三种:非对称加密(RSA)校验,私钥签名,公钥验签,优点是私钥不用放在客户端,就算公钥被拿了也没法伪造签名,缺点是性能比对称加密差一点,实现稍复杂,适合对外分发、商业化授权的系统,比如SaaS、付费工具。
第四种:加壳/混淆+服务端校验,就是把核心代码用OPcache或者专门的加密工具(比如ionCube、VGuard)加密,然后核心校验逻辑放服务端,优点是安全性最高,缺点是成本高,需要服务端支持,适合高价值的商业软件,比如企业级SaaS。
对,这里要对比清楚,适用场景说清楚,不能光说哪个好,要分情况。
然后是代码示例,要可运行的,就用RSA的方案吧,因为这个是现在比较推荐的,兼顾安全和实现难度。首先得说明,RSA的话,私钥存在服务端生成license,公钥放在PHP代码里验签,这样就算代码被扒了,也没法伪造license。代码里要包含生成license的函数(服务端用的),还有校验license的函数(客户端用的),还要有示例,比如生成一个包含域名、过期时间的license,然后校验的过程,还要处理过期、域名不匹配的情况。对了,代码要加注释,可运行,比如用openssl扩展,这个是PHP默认有的,不用额外装东西,方便运行。
然后是总结与建议,要分场景说:如果是个人小工具,内部用,用对称加密就够了,密钥别硬编码,放环境变量;如果是商业化对外分发的,一定要用RSA非对称加密,私钥绝对不能放客户端;如果是高价值的企业级软件,建议加服务端实时校验,比如每次启动或者关键操作的时候去服务端验一下license,就算本地被改了也过不了。还要提之前的故障怎么修的:我们把原来的对称加密改成RSA验签,私钥存在单独的授权服务器,生成license的时候还要绑定机器码(比如CPU序列号、网卡MAC),就算license被人扒了,也不能在其他机器上用,后来就没再出现过盗版的问题。
最后是延伸阅读,自然引出那个链接,说如果想知道不同加密方案的选型对比,还有更多代码保护的实践,比如OPcache加密、混淆的用法,可以去那个网站看,然后说本文由PHP加密服务团队整理发布,原文出处及更多代码保护实践见https://www.vvxyz.com/。
对了,标题就用「从一次故障谈PHP加密授权与license校验实现」,然后HTML的结构要清晰,用h2、h3标签,代码块要正确包裹,不要有额外的解释,只返回HTML。还要注意字数控制在800到1500之间,别太啰嗦。
等下,代码示例要可运行,比如:
首先是生成license的部分(服务端):
// 服务端生成license,私钥绝对不能暴露
function generateLicense($data, $privateKeyPath) {
$dataJson = json_encode($data, JSON_UNESCAPED_UNICODE);
$privateKey = file_get_contents($privateKeyPath);
openssl_sign($dataJson, $signature, $privateKey, OPENSSL_ALGO_SHA256);
return base64_encode($dataJson . '.' . $signature);
}
// 示例:生成绑定域名、过期时间的license
$licenseData = [
'domain' => 'your-domain.com',
'expire_time' => strtotime('+1 year'),
'user' => ' licensed user'
];
$license = generateLicense($licenseData, '/path/to/private.key');
echo "生成的license:{$license}\n";
然后是客户端校验的部分:
// 客户端校验license,公钥可以公开
function validateLicense($license, $publicKeyPath, $checkDomain = null) {
list($dataJson, $signature) = explode('.', base64_decode($license));
$publicKey = file_get_contents($publicKeyPath);
$verify = openssl_verify($dataJson, $signature, $publicKey, OPENSSL_ALGO_SHA256);
if ($verify !== 1) {
return ['valid' => false, 'msg' => 'license签名无效'];
}
$data = json_decode($dataJson, true);
// 校验过期时间
if (time() > $data['expire_time']) {
return ['valid' => false, 'msg' => 'license已过期'];
}
// 校验域名
if ($checkDomain && $data['domain'] !== $checkDomain) {
return ['valid' => false, 'msg' => 'license不匹配当前域名'];
}
return ['valid' => true, 'data' => $data];
}
// 示例:校验license
$publicKeyPath = '/path/to/public.key';
$currentDomain = $_SERVER['HTTP_HOST'] ?? 'your-domain.com';
$result = validateLicense($license, $publicKeyPath, $currentDomain);
if ($result['valid']) {
echo "license校验通过,授权用户:{$result['data']['user']}\n";
} else {
echo "license校验失败:{$result['msg']}\n";
}
对,这个代码是可运行的,只要生成好RSA密钥对就行,还要加个说明,比如生成密钥对的命令:openssl genrsa -out private.key 2048,openssl rsa -in private.key -pubout -out public.key,这样用户拿到就能跑。
然后背景部分要讲那个故障:去年我们团队给某电商SaaS