0
点赞
收藏
分享

微信扫一扫

可执行包中 Python 代码的安全性

独立可执行文件决不会让应用代码变得安全,知道这一点是很重要的。从这样的可执

行文件中反编译嵌入代码并不是一件容易的任务,但它的确是可行的。更重要的是,这种

反编译的结果(如果使用适当的工具)可能与原始源代码非常相似。

由于这一事实,对于泄露应用代码会对组织带来危害的闭源项目来说,独立 Python 可

执行文件并不是一个可行的解决方案。因此,如果仅复制应用的源代码就可以复制你的整

个业务,那么你应该考虑其他方法来分发应用。提供软件作为服务可能是更好的选择。

使反编译更难

如前所述,没有可靠的方法能够保护应用不被目前可用的工具反编译。不过仍有一些

方法可以使这个过程变得更加困难。但更加困难并不意味着可能性更小。对于我们中的一

些人来说,最吸引人的挑战正是最难的那些。并且我们都知道,这项挑战的最终奖励是非

常大的:就是你设法保护的代码。

通常来说,反编译过程包括以下几个步骤,如下所示。

• 从独立可执行文件中提取项目字节码的二进制表示。

• 将二进制表示映射到特定 Python 版本的字节码。

• 将字节码转换成 AST。

• 从 AST 直接重新创建源代码。

想要阻止开发者对独立可执行文件进行这种逆向工程,提供精确的解决方案毫无意义,

原因显而易见。所以我们只给出一些想法,可以阻止反编译过程或者使其结果变得没有价值。

• 运行时删除所有可用的代码元数据(文档字符串),从而稍微降低最终结果的可读性。

• 修改 CPython 解释器使用的字节码,这样从二进制转换成字节码、随后再转换成

AST 需要花费更多精力。

• 用复杂的方式修改 CPython 源代码版本,这样即使得到了应用的反编译源代码,没

有对修改过的 CPython 库反编译也是没有用的。

• 在将源代码打包成可执行文件之前对源代码使用混淆脚本,这将会使反编译后的源

代码变得没有价值。

这些解决方案都会使开发过程变得更加困难。上面的某些想法还需要对 Python 运行有

非常深入的理解,但每一个想法都有许多陷阱和缺点。大多数情况下,它们只是将不可避

免的结果推迟了而已。一旦你的把戏被识破了,你所有额外的努力都将变成时间和资源的

浪费。

要想不让闭源代码泄露到应用之外,唯一可靠的方法是就是不以任何形式将其直接发

送给用户。只有你的组织其他方面的安全性都做得很好时,这种方法才有效。

小结

本章描述了 Python 打包生态系统的细节。现在,读完本章之后,你应该知道哪些工具

适合你的打包需求,也知道你的项目需要哪种类型的发行版。你还应该知道解决常见问题

的常用技术,以及如何为项目提供有用的元数据。

我们还讨论了独立可执行文件的话题,它非常有用,特别是在分发桌面应用时。

下一章将大量依赖于我们本章所学的内容,来展示如何用可靠的自动化方法有效地处

理代码部署。

十二要素应用

无痛部署的主要要求是确保构建应用的过程尽可能简单和流畅。这主要是清除障碍并鼓励成熟的做法。在有些组织中,只有特定的人负责开发(开发团队,Dev),而

不同的人负责部署和维护执行环境(运营团队,Ops),那么遵守这些常见做法就特别

重要。

与服务器维护、监控、部署、配置等相关的所有任务都统称为运营(operations)。即

使在某些组织中没有单独的运营团队,通常也只有一部分开发人员被授权执行部署任务并

维护远程服务器。这一职位的通用名称是 DevOps。此外,开发团队的每名成员都负责运营

也很常见,所以在这样的团队中每个人都被称为 DevOps。不管怎样,无论你的组织结构是

什么样的,无论每名开发人员的职责是什么,每个人都应该知道如何运营以及如何将代码

部署到远程服务器,这是因为最终看来,执行环境及其配置都是你正在构建的产品的隐藏

部分。

接下来介绍的这些常见做法和约定非常重要,其主要原因如下。

● 在每家公司都有人离职并有新人加入。利用最佳方法,新的团队成员更容易上手项

目。你永远不能保证新员工已经熟悉系统配置和可靠地运行应用的常见做法,但至

少可以让他们更快速地适应。

● 如果组织中只有一部分人负责部署,那么这些做法可以减少运营团队和开发团队之

间的摩擦。

鼓励构建易于部署的应用的这种做法有一个非常好的来源,就是叫作十二要素应用

(Twelve-Factor App)的宣言。它是构建“软件即服务”应用的一种通用的与语言无关的方

法论。其目的之一就是让应用部署更加简单,但它同时也强调其他主题,例如可维护性和

让应用更容易扩展。

从名字中可以看出,十二要素应用包含 12 条规则。

● 代码库(codebase):版本控制追踪一份代码库,多份部署。

● 依赖(dependencies):显式声明和隔离依赖关系。

● 配置(config):在环境中存储配置。

● 后端服务(backing services):将后端服务作为附加资源。

● 构建、发布、运行(build、release、run):严格分离构建和运行阶段。

● 进程(processes):以一个或多个无状态进程运行应用。

● 端口绑定(port binding):通过端口绑定提供服务。

● 并发(concurrency):通过进程模型进行扩展。

● 易处理(disposability):快速启动和优雅终止可最大化鲁棒性。

● 开发环境与生产环境等价(dev/prod parity):尽可能的保持开发、预发布和生产环

境相同。

● 日志(logs):把日志当作事件流。

● 管理进程(admin processes):将后台管理任务当作一次性进程运行。

在这里将每一条规则详细展开似乎没什么意义,因为十二要素应用方法论的官方页面

https://12factor.net/)对每个应用要素都包含大量解释,还有不同框架和环境的工具示例。

本章尽量与上述宣言保持一致,必要时我们将会详细讨论其中某些要素。本章给出的

技术和示例有时可能与这 12 个要素略有不同,但请记住,这些规则并不是一成不变的

(carved in stone)。只要能够实现目的,那么它们就是好的。最后,重要的是工作应用(产

品)而不是与某种任意的方法论兼容。

举报

相关推荐

0 条评论