PHP内核探索:代码的加密与解密

可以避免直接分发源代码
服务器君一共花费了270.348 ms进行了6次数据库查询,努力地为您提供了这个页面。
试试阅读模式?希望听取您的建议

PHP语言作为脚本语言的一种,由于不需要进行编译,所以通常PHP程序的分发都是直接发布源代码。 对于一些开源软件来说,这并没有什么问题,因为它本来就希望有更多的人阅读代码,希望有更多的人参与进来, 而对于商业代码来说,这却是一个不太好的消息,不管是从商业秘密,还是从对公司产权的保护来说却是一个问题, 基于此,从而引出了对PHP代码的加密和解密的议题。 例如国内的Discuz论坛程序在开源之前要运行是必须安装Zend Optimizer的, Zend官方的代码加密软件是Zend Guard, 可以用来加密和混淆PHP代码,这样分发出去的代码就可以避免直接分发源代码, 不过加密后的代码是无法直接运行的,在运行时还需要一个解密的模块来运行加密后的程序, 要运行Zend Guard加密后的代码需要安装Zend Optimizer(PHP5.2之前的版本), 或者安装Zend Guard Loader(PHP5.3版本)扩展才能运行。

加密的本质

本质上程序在运行时都是在执行机器码,而基于虚拟机的语言的加密通常也是加密到这个级别, 也就是说PHP加密后的程序在执行之前都会解密成opcode来执行。

PHP在执行之前有一个编译的环节,编译的结果是opcode,然后由Zend虚拟机执行, 从这里看如果只要将源代码加密,然后在执行之前将代码解密即可。

从这里看,只要代码能被解密为opcode,那么总有可能反编译出来源代码, 其他的语言中也是类似,比如objdump程序能将二进制程序反汇编出来, .NET、Java的程序也是一样,都有一些反编译的程序,不过通常这些厂商同时还会 附带代码混淆的工具,经过混淆的代码可读性极差,很多人都留意过Gmail等网站 经过混淆的JS代码吧,他们阅读起来非常困难,经过混淆的代码即使反编译出来, 读者也很难通过代码分析出代码中的逻辑,这样也就极大的增加了应用的安全性。

简单的代码加密解密实战

根据前文的介绍,作为实例,本文将编写一个简单的代码加密扩展用于对PHP代码的加密, 我们只需要能把源码加密,简单通过浏览源代码的方法无法获取到源代码那我们的目标就达到了, 为了能正确执行加密后的代码,我们还需要另一个模块:解密模块。

简单的思路是把所有的PHP文件代码进行加密,同时另存为同名的PHP文件, 这是一种很简单的做法,只是为了防止源代码赤裸裸的暴露在代码中。

加密也有很多种做法,第一种简单的方法可以简单的把源码本身进行一些可逆加密, 这样我们可以在运行之前把真实的源码反解出来执行,不过这种方式存在一种问题, 只要知道了加密算法我们就可以把代码给解出来,采用这种方式唯一能做的就是尽量 增加加密的复杂度,既然正式的代码在运行之前会被转化成PHP源代码,通过hack的方式是可以 完完整整的获得PHP源码的,保密的效果就很有限了。

因为Zend引擎最终执行的是opcode,那么我们只要保证能解密出opcode则能满足需求, 我们只要简单的将opcode进行简单的序列化或者像Zend Guard那样进行混淆, 在运行之前将opcode还原,那么源代码的信息就不存在了,这样我们就能保证源代码的安全, 而不至于泄露。

加密

前面提到加密的目的就是为了防止轻易获取程序源码的一种手段,对于PHP来说, 将源码编译为opcode已经能达到目的了,因为PHP引擎最终都是需要执行opcode的。 虽然可以将加密进一步,但是如果需要修改Zend引擎,那么成本就有点大了,因为需要修改 Zend引擎了,而这是无法通过简单的扩展机制来实现了,所以解密的成本也会变的太大, 也就没有实际意义了。

在本例中为了方便,代码的加密和解密实现均实现在同一个模块中。

熟悉PHP的同学可能会发现,这种加密方式和opcode缓存本质上没有太大差别,opcode缓存的工作是将 源码编译为opcode然后缓存起来,在执行的时候绕过编译直接执行opcode,的确是没错的。这里唯一的区别是: opcode缓存是动态透明的,而加密后我们要做的是分发加密后的代码。这么说我们是不是可以直接将 APC之类的缓存扩展进行改造就可以了,其实理论上是可以的。不过这两者的定位还是有差别的: 加密的目的是为了减少源码被分析破解的可能,而缓存只是为了提高程序运行的速度。

解密

本例中的代码其实并没有进行加密,相对源代码来说,opcode编译本身也可以算做一种加密了, 因为毕竟通过阅读opcode来理解程序的逻辑还是比较困难的。

延伸阅读

此文章所在专题列表如下:

  1. PHP内核探索:从SAPI接口开始
  2. PHP内核探索:一次请求的开始与结束
  3. PHP内核探索:一次请求生命周期
  4. PHP内核探索:单进程SAPI生命周期
  5. PHP内核探索:多进程/线程的SAPI生命周期
  6. PHP内核探索:Zend引擎
  7. PHP内核探索:再次探讨SAPI
  8. PHP内核探索:Apache模块介绍
  9. PHP内核探索:通过mod_php5支持PHP
  10. PHP内核探索:Apache运行与钩子函数
  11. PHP内核探索:嵌入式PHP
  12. PHP内核探索:PHP的FastCGI
  13. PHP内核探索:如何执行PHP脚本
  14. PHP内核探索:PHP脚本的执行细节
  15. PHP内核探索:操作码OpCode
  16. PHP内核探索:PHP里的opcode
  17. PHP内核探索:解释器的执行过程
  18. PHP内核探索:变量概述
  19. PHP内核探索:变量存储与类型
  20. PHP内核探索:PHP中的哈希表
  21. PHP内核探索:理解Zend里的哈希表
  22. PHP内核探索:PHP哈希算法设计
  23. PHP内核探索:翻译一篇HashTables文章
  24. PHP内核探索:哈希碰撞攻击是什么?
  25. PHP内核探索:常量的实现
  26. PHP内核探索:变量的存储
  27. PHP内核探索:变量的类型
  28. PHP内核探索:变量的值操作
  29. PHP内核探索:变量的创建
  30. PHP内核探索:预定义变量
  31. PHP内核探索:变量的检索
  32. PHP内核探索:变量的类型转换
  33. PHP内核探索:弱类型变量的实现
  34. PHP内核探索:静态变量的实现
  35. PHP内核探索:变量类型提示
  36. PHP内核探索:变量的生命周期
  37. PHP内核探索:变量赋值与销毁
  38. PHP内核探索:变量作用域
  39. PHP内核探索:诡异的变量名
  40. PHP内核探索:变量的value和type存储
  41. PHP内核探索:全局变量Global
  42. PHP内核探索:变量类型的转换
  43. PHP内核探索:内存管理开篇
  44. PHP内核探索:Zend内存管理器
  45. PHP内核探索:PHP的内存管理
  46. PHP内核探索:内存的申请与销毁
  47. PHP内核探索:引用计数与写时复制
  48. PHP内核探索:PHP5.3的垃圾回收机制
  49. PHP内核探索:内存管理中的cache
  50. PHP内核探索:写时复制COW机制
  51. PHP内核探索:数组与链表
  52. PHP内核探索:使用哈希表API
  53. PHP内核探索:数组操作
  54. PHP内核探索:数组源码分析
  55. PHP内核探索:函数的分类
  56. PHP内核探索:函数的内部结构
  57. PHP内核探索:函数结构转换
  58. PHP内核探索:定义函数的过程
  59. PHP内核探索:函数的参数
  60. PHP内核探索:zend_parse_parameters函数
  61. PHP内核探索:函数返回值
  62. PHP内核探索:形参return value
  63. PHP内核探索:函数调用与执行
  64. PHP内核探索:引用与函数执行
  65. PHP内核探索:匿名函数及闭包
  66. PHP内核探索:面向对象开篇
  67. PHP内核探索:类的结构和实现
  68. PHP内核探索:类的成员变量
  69. PHP内核探索:类的成员方法
  70. PHP内核探索:类的原型zend_class_entry
  71. PHP内核探索:类的定义
  72. PHP内核探索:访问控制
  73. PHP内核探索:继承,多态与抽象类
  74. PHP内核探索:魔术函数与延迟绑定
  75. PHP内核探索:保留类与特殊类
  76. PHP内核探索:对象
  77. PHP内核探索:创建对象实例
  78. PHP内核探索:对象属性读写
  79. PHP内核探索:命名空间
  80. PHP内核探索:定义接口
  81. PHP内核探索:继承与实现接口
  82. PHP内核探索:资源resource类型
  83. PHP内核探索:Zend虚拟机
  84. PHP内核探索:虚拟机的词法解析
  85. PHP内核探索:虚拟机的语法分析
  86. PHP内核探索:中间代码opcode的执行
  87. PHP内核探索:代码的加密与解密
  88. PHP内核探索:zend_execute的具体执行过程
  89. PHP内核探索:变量的引用与计数规则
  90. PHP内核探索:新垃圾回收机制说明

本文地址:http://www.nowamagic.net/librarys/veda/detail/1544,欢迎访问原出处。

不打个分吗?

转载随意,但请带上本文地址:

http://www.nowamagic.net/librarys/veda/detail/1544

如果你认为这篇文章值得更多人阅读,欢迎使用下面的分享功能。
小提示:您可以按快捷键 Ctrl + D,或点此 加入收藏

大家都在看

阅读一百本计算机著作吧,少年

很多人觉得自己技术进步很慢,学习效率低,我觉得一个重要原因是看的书少了。多少是多呢?起码得看3、4、5、6米吧。给个具体的数量,那就100本书吧。很多人知识结构不好而且不系统,因为在特定领域有一个足够量的知识量+足够良好的知识结构,系统化以后就足以应对大量未曾遇到过的问题。

奉劝自学者:构建特定领域的知识结构体系的路径中再也没有比学习该专业的专业课程更好的了。如果我的知识结构体系足以囊括面试官的大部分甚至吞并他的知识结构体系的话,读到他言语中的一个词我们就已经知道他要表达什么,我们可以让他坐“上位”毕竟他是面试官,但是在知识结构体系以及心理上我们就居高临下。

所以,阅读一百本计算机著作吧,少年!

《UNIX环境高级编程(第2版)》 史蒂文斯 (作者), 拉戈 (作者), 尤晋元 (译者), 张亚英 (译者), 戚正伟 (译者)

《UNIX环境高级编程(第2版)》是被誉为UNIX编程“圣经”的Advanced Programming in the UNIX Environment一书的更新版。在本书第1版出版后的十几年中,UNIX行业已经有了巨大的变化,特别是影响UNIX编程接口的有关标准变化很大。本书在保持了前一版的风格的基础上,根据最新的标准对内容进行了修订和增补,反映了最新的技术发展。书中除了介绍UNIX文件和目录、标准I/O库、系统数据文件和信息、进程环境、进程控制、进程关系、信号、线程、线程控制、守护进程、各种I/O、进程间通信、网络IPC、伪终端等方面的内容,还在此基础上介绍了多个应用示例,包括如何创建数据库函数库以及如何与网络打印机通信等。

更多计算机宝库...