PHP文件加密解


<?php

/** 
 * 公钥加密 
 * 
 * @param string 明文 
 * @param string 证书文件(.crt) 
 * @return string 密文(base64编码) 
 */  
function publickey_encodeing($sourcestr, $fileName)  
{  
    $key_content = file_get_contents($fileName);  
    $pubkeyid    = openssl_get_publickey($key_content);  
      
    if (openssl_public_encrypt($sourcestr, $crypttext, $pubkeyid))  
    {  
        return base64_encode("".$crypttext);  
    }  
}  
/** 
 * 私钥解密 
 * 
 * @param string 密文(二进制格式且base64编码) 
 * @param string 密钥文件(.pem / .key) 
 * @param string 密文是否来源于JS的RSA加密 
 * @return string 明文 
 */  
function privatekey_decodeing($crypttext, $fileName, $fromjs = FALSE)  
{  
    $key_content = file_get_contents($fileName);  
    $prikeyid    = openssl_get_privatekey($key_content);  
    $crypttext   = base64_decode($crypttext);  
    $padding = $fromjs ? OPENSSL_NO_PADDING : OPENSSL_PKCS1_PADDING;  
    if (openssl_private_decrypt($crypttext, $sourcestr, $prikeyid, $padding))  
    {  
        return $fromjs ? rtrim(strrev($sourcestr), "/0") : "".$sourcestr;  
    }  
    return ;  
}  
//JS->PHP 测试  
$txt_en = $_POST['password'];  
$txt_en = base64_encode(pack("H*", $txt_en));  
$file = 'ssl/server.pem';  
$txt_de = privatekey_decodeing($txt_en, $file, TRUE);  
var_dump($txt_de);  
//PHP->PHP 测试  
$data = "汉字:1a2b3c";  
$config = Core::getInstance()->config;  
$file1 = 'ssl/server.crt';  
$file2 = 'ssl/server.pem';  
$a = publickey_encodeing($data, $file1);  
$b = privatekey_decodeing($a, $file2);  
var_dump($b); 

?>

php是脚本语言,发布后源码容易暴露,尤其是在使用虚拟主机的时候,如果用Zend Encoder加密后,相当于在源码上加了一层保护,而且据说还加快了程序的运行速度,我们为什么不使用它呢,呵呵.
安装软件时,在选择安将目录后会有一个对话框让你选择许可证的地址,这里我们选择下面的在本地磁盘查找,然后在接下的的对话框中输入我们下载到的许可证文件“zend_encoder.dat”的路径(压缩包的“crack”文件夹里)。
软件的使用方法非常的简单,首先选择“File->NewProject”新建一个项目,然后在该项目下添加你要加密的文件或文件夹。在右边的“Target Directory”选项里输入保存加密PHP文件的路径。然后点“Encode”按钮就可以对当前项目中的PHP文件进行加密了。你还可以将当前项目保存起来,以便你的PHP文件更新后重新加密。PHP文件加密后,文件大小也变得小多了,以前一个30K的文件加密后只有14K。
技巧:在“Tools->Settings”对话框的“Extensions to Encoder”文本框中你可以对要加密的文件扩展名进行指定(多个扩展名用空格分隔),使Zend Encoder只对这些文件进行加密。

PHP Zend 解密

第一种方式使用方便,不需要对php服务器进行配置,或加载其他模块,因此可以方便地部署在租用空间的服务器上。对文件进行加密也很简单,只需要把php文件上传到加密网站,就可以生成加密之后的文件,替换原来的php文件之后就可以正常运行了。

第二种方式使用起来相对复杂一些, php服务器上需要加载额外的模块。对于租用空间,没有管理员权限的用户来说,这是一个问题。

通过分析,我们得出以下显而易见的一些结论:

l  因为没有加载php扩展,因此加密之后的文件的执行过程仍然完全遵循图1中的流程。因此,加密之后的文件本身应该是一个完全符合php语法要求的,可以被php编译器正确解析,并可以被php vm正确执行的文件。

l  那么,解密的过程只能是在这个加密之后的文件的执行过程中进行的,也就是说,这个加密之后的php文件是一个可以自解密的php文件,这个文件中包含了所有解密过程中需要用到的信息。因此,拥有了这个加密之后的文件,其实也同时拥有了解密所需的所有信息:解密的方法、和解密过程中所需的数据。

l  无论解密过程如何,最后一定是解密出原来的明文内容,然后进行执行的,否则就不符合图1的执行流程了。

 

现在,我们可以思考如何进行解密了:

l  一种方式,模拟执行这个加密的php文件,因为这个文件是自解密的,因此,最后一定可以得到明文。

这种方式是最容易想到的,但比较难于执行,并且这个文件中可能包含多个执行陷阱,扰乱模拟执行的过程。

l  另一种方式,直接在PHP环境中真实地执行这个加密的php文件,在php的内部得到解密之后的明文。

php中,把一段文本作为代码进行执行,我知道的有以下几种方式:

u  把文本保存到另一个文件,include这个文件进行。

u  使用eval函数,直接执行这段文本。

参考这个eval的处理函数,Zend\zend_vm_execute.h2529行的ZEND_INCLUDE_OR_EVAL_SPEC_CONST_HANDLER函数,和Zend\zend_execute_API.c中第1156行的zend_eval_string1函数。

u  使用包含执行功能的其它函数。

比如,preg_replace函数,在pattern中指定e(PREG_REPLACE_EVAL)作为参数,就会先执行参数中的文本,然后执行替换(这个参数在php5.5将不再支持)。参考preg_replace函数的处理函数,ext\pcre\php-pcre.c中第1003行的php_pcre_replace_impl函数,和第897preg_do_eval函数。

 

为了看起来更安全,很多进行加密的都不会选择include方式,而会选择后两种。其实三种方式的安全性是一样的,没有任何差别。因为无论哪种方式,都遵循图1中的执行流程。

 

那么,我们在图1中的Zend\zend_language_scanner.c中的compile_string函数中增加一个输出,把所有需要编译文本输出出来,其中一定有解密之后的明文。

 

一些问题:

l  为什么不使用include/require

因为使用include方式,需要生成一个包含明文的文件,可能加密厂商认为这样不安全,怕别人找到这个文件,所以大部分不使用这种方式。



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值