ChatGPT解决这个技术问题 Extra ChatGPT

如何保护 Python 代码不被用户阅读?

我正在用 Python 开发一个软件,该软件将分发给我雇主的客户。我的雇主想通过有时间限制的许可证文件来限制软件的使用。

如果我们分发 .py 文件甚至 .pyc 文件,则很容易(反编译和)删除检查许可证文件的代码。

另一方面是我的雇主不希望我们的客户阅读代码,担心代码可能被盗或至少是“新颖的想法”。

有没有好的方法来处理这个问题?

py2exe 只是将 .pyc 字节码文件存储在 .zip 存档中,因此这绝对不是解决方案。尽管如此,当与合适的启动脚本结合使用以使其在 Linux 下运行时,这仍然很有用
这是对您问题的最全面的回答:wiki.python.org/moin/Asking%20for%20Help/…
您唯一能做的就是使用许可和远程后端来完成操作。重要的代码将放置在后端,因此对于客户端应用程序而言,后端将充当黑匣子。没有人知道这些网络调用的背后是什么,因此您的重要代码将受到保护。如果许可证过期,网络调用将未经身份验证。这是我能想到的为最终用户隐藏重要代码的唯一解决方案。
您始终可以通过将软件连接到服务器来增加价值,即更新,

s
somebody_other

“有什么好办法处理这个问题吗?”不会。没有任何东西可以防止逆向工程。甚至 DVD 机器上的固件也被逆向工程并暴露了 AACS Encryption key。尽管 DMCA 将其定为刑事犯罪。

由于没有任何技术方法可以阻止您的客户阅读您的代码,因此您必须使用普通的商业方法。

许可证。合同。条款和条件。即使人们可以阅读代码,这仍然有效。请注意,您的某些基于 Python 的组件可能要求您在销售使用这些组件的软件之前支付费用。此外,一些开源许可证禁止您隐藏该组件的来源。提供重要价值。如果你的东西非常好——价格难以拒绝——就没有动力浪费时间和金钱对任何东西进行逆向工程。逆向工程很昂贵。让你的产品稍微便宜一点。提供升级和增强功能,使任何逆向工程都成为一个坏主意。当下一个版本破坏他们的逆向工程时,就没有意义了。这可能会走极端,但您应该提供新功能,使下一个版本比逆向工程更有价值。以极具吸引力的价格提供定制服务,以至于他们宁愿付钱给您来构建和支持增强功能。使用过期的许可证密钥。这很残忍,会给你带来坏名声,但它肯定会让你的软件停止工作。将其作为 Web 服务提供。 SaaS 不涉及向客户下载。


第 2 点更为重要。如果它比逆向工程更便宜,加上每年更新,没有人会尝试,即使这样做,也没有人会付钱给黑客而不是软件供应商。
确实如此。在大多数情况下,逆向工程是可行的,但成本很高。 @S.Lott,我相信第 6 点基于这个问题更重要。如果源代码确实需要保护,那么它应该远离最终用户。
问题:“有没有什么好方法可以保护我的家人和我自己在睡梦中不被入侵者谋杀?”互联网:“不。任何人都可以找到,没有任何住所是 100% 不可穿透的。凡人家庭是这项工作的错误工具。”
第 5 点不能应用于相同的假设,即它可以被逆向工程和破解。
N
Ned Batchelder

Python 作为一种字节码编译的解释语言,很难锁定。即使您使用像 py2exe 这样的 exe 打包程序,可执行文件的布局也是众所周知的,并且 Python 字节码也很容易理解。

通常在这种情况下,您必须做出权衡。保护代码到底有多重要?那里有真正的秘密(例如银行转账对称加密的密钥),还是你只是偏执?选择可以让您最快开发出最佳产品的语言,并对您的新颖想法的价值保持现实。

如果您决定确实需要安全地执行许可证检查,请将其编写为一个小的 C 扩展,以便许可证检查代码可以非常困难(但并非不可能!)进行逆向工程,并将大部分代码留在 Python 中.


即使许可证检查代码因为是用 C 编写的而难以进行逆向工程,但删除对许可证检查代码的调用不是相对容易吗?
是的,这取决于执行许可证检查的位置。如果有很多呼叫扩展,可能很难根除。或者,您也可以将应用程序的一些其他关键部分移动到许可证检查中,以便删除对扩展程序的调用会削弱应用程序。
真的,所有这些工作都不是为了防止修改,而是为了增加难度,使其不再值得。如果有足够的好处,任何东西都可以进行逆向工程和修改。
@Blair Conrad:如果许可证检查代码也隐藏了功能,则不会。例如mylicensedfunction(licenseblob liblob, int foo, int bar, std::string bash)
我实际上已经看到商业 python 代码作为 C 库中的嵌入式 python 交付。他们没有将代码的某些部分转换为 C,而是将整个 python 代码隐藏在保护性 C 层中。然后,如果他们想要一个可由 python 导入的模块,他们会在 C 之上编写一个精简的 python 扩展。开源是一种更简单的生活方式。
J
Jeff Mercado

Python 不是你需要的工具

你必须使用正确的工具来做正确的事,而 Python 的设计初衷不是为了混淆。恰恰相反;在 Python 中,一切都是开放的或易于显示或修改的,因为这是该语言的哲学。

如果您想要一些无法看穿的东西,请寻找其他工具。这不是一件坏事,重要的是存在用于不同用途的几种不同工具。

混淆真的很难

即使是编译好的程序也可以进行逆向工程,所以不要认为你可以完全保护任何代码。您可以分析混淆的PHP,破解flash加密密钥等。新版本的Windows每次都被破解。

有法律要求是一个好方法

您无法阻止某人滥用您的代码,但您可以轻松发现是否有人这样做。因此,这只是一个偶然的法律问题。

代码保护被高估了

如今,商业模式倾向于销售服务而不是产品。您不能复制服务、盗版或窃取服务。也许是时候考虑顺其自然了……


Python 不是您需要的工具。 Malbolge 是。 :)
很好的答案,但是“临时法律问题”?真的吗?你住在哪里,你有任何偶然的法律问题?
我认为,如果我们有一个频率——昂贵的混淆代码被黑客攻击的频率——我们可以说使用 Python 和混淆代码的实用性。
如果有人这样做,您将如何“轻松发现”?
这是一个观点,而不是技术答案。我同意混淆并不意味着您的代码被完全锁定,但它确实可以防止低级黑客攻击,并且根据您的用例是有意义的。
Z
Ziv

编译python并分发二进制文件!

明智的想法:

使用 CythonNuitkaShed Skin 或类似的东西将 python 编译为 C 代码,然后将您的应用程序作为 python 二进制库 (pyd) 分发。

这样一来,就不会留下任何 Python(字节)代码,而且我认为您已经完成了任何人(即您的雇主)可以从常规代码中获得的任何合理数量的模糊处理。 (.NET 或 Java 没有这种情况安全,因为该字节码没有被混淆,并且可以相对容易地被反编译成合理的源代码。)

Cython 越来越兼容 CPython,所以我认为它应该可以工作。 (我实际上正在为我们的产品考虑这个。我们已经在构建一些第三方库作为 pyd/dlls,所以将我们自己的 python 代码作为二进制文件发布对我们来说并不是一个太大的步骤。)

有关如何执行此操作的教程,请参阅 This Blog Post(不是我的)。 (谢谢@hithwen)

疯狂的想法:

您可能会让 Cython 为每个模块单独存储 C 文件,然后将它们全部连接起来并使用大量内联构建它们。这样一来,您的 Python 模块就非常单一,难以使用常用工具进行处理。

超越疯狂:

如果您可以静态链接到(并优化)python 运行时和所有库(dll),您可能能够构建单个可执行文件。这样,肯定很难拦截到/来自 python 和您使用的任何框架库的调用。但是,如果您使用的是 LGPL 代码,则无法做到这一点。


使用 cython 编译是否可以与 python 3.4 Django 应用程序一起使用,或者可以在不付出大量努力的情况下使其工作?
@丹尼尔:不确定。没试过Django。随意发布一个新的问题。
@mlvljr FWIW,恕我直言,编译为二进制文件是在出售所有机密和试图防止 NSA 级逆向工程之间的一个很好的权衡。尤其是如果你有一个庞大的 Python 代码库和偏执的理由。 ;)
hithwen 的 POST 现在无效了。
b
bhadra

我了解您希望您的客户使用 python 的强大功能,但不想公开源代码。

以下是我的建议:

(a) 将代码的关键部分编写为 C 或 C++ 库,然后使用 SIPswig 将 C/C++ API 公开给 Python 命名空间。

(b) 使用 cython 而不是 Python

(c) 在 (a) 和 (b) 中,应该可以将库作为具有 Python 接口的许可二进制文件分发。


我只是按照 TyPyPy 的建议看了一下 Shed Skin,它似乎是非常好的东西!
L
Lmwangi

你看过pyminifier吗?它会缩小、混淆和压缩 Python 代码。对于随意的逆向工程来说,示例代码看起来很讨厌。

$ pyminifier --nonlatin --replacement-length=50 /tmp/tumult.py
#!/usr/bin/env python3
ﺭ异𞸐𐤔ﭞﰣﺁں𝕌𨿩𞸇뻛𐬑𥰫嬭ﱌ𢽁𐡆𧪮Ꝫﴹ뙫𢤴퉊ﳦﲣפּܟﺶ𐐤ﶨࠔ𐰷𢡶𧐎𐭈𞸏𢢘𦘼ﶻ𩏃𦽨𞺎𠛘𐠲䉊ﰸﭳᣲמּ=ImportError
ﺭ异𞸐𐤔ﭞﰣﺁں𝕌𨿩𞸇뻛𐬑𥰫嬭ﱌ𢽁𐡆𧪮Ꝫﴹ뙫𢤴퉊ﳦﲣפּܟﺶ𐐤ﶨࠔ𐰷𢡶𧐎𐭈𞸏𢢘𦘼ﶻ𩏃𦽨𞺎𠛘𐠲䉊ﰸﭳᣲ燱=print
ﺭ异𞸐𐤔ﭞﰣﺁں𝕌𨿩𞸇뻛𐬑𥰫嬭ﱌ𢽁𐡆𧪮Ꝫﴹ뙫𢤴퉊ﳦﲣפּܟﺶ𐐤ﶨࠔ𐰷𢡶𧐎𐭈𞸏𢢘𦘼ﶻ𩏃𦽨𞺎𠛘𐠲䉊ﰸﭳᣲ巡=False
ﺭ异𞸐𐤔ﭞﰣﺁں𝕌𨿩𞸇뻛𐬑𥰫嬭ﱌ𢽁𐡆𧪮Ꝫﴹ뙫𢤴퉊ﳦﲣפּܟﺶ𐐤ﶨࠔ𐰷𢡶𧐎𐭈𞸏𢢘𦘼ﶻ𩏃𦽨𞺎𠛘𐠲䉊ﰸﭳᣲ澨=object
try:
 import demiurgic
except ﺭ异𞸐𐤔ﭞﰣﺁں𝕌𨿩𞸇뻛𐬑𥰫嬭ﱌ𢽁𐡆𧪮Ꝫﴹ뙫𢤴퉊ﳦﲣפּܟﺶ𐐤ﶨࠔ𐰷𢡶𧐎𐭈𞸏𢢘𦘼ﶻ𩏃𦽨𞺎𠛘𐠲䉊ﰸﭳᣲמּ:
 ﺭ异𞸐𐤔ﭞﰣﺁں𝕌𨿩𞸇뻛𐬑𥰫嬭ﱌ𢽁𐡆𧪮Ꝫﴹ뙫𢤴퉊ﳦﲣפּܟﺶ𐐤ﶨࠔ𐰷𢡶𧐎𐭈𞸏𢢘𦘼ﶻ𩏃𦽨𞺎𠛘𐠲䉊ﰸﭳᣲ燱("Warning: You're not demiurgic. Actually, I think that's normal.")
try:
 import mystificate
except ﺭ异𞸐𐤔ﭞﰣﺁں𝕌𨿩𞸇뻛𐬑𥰫嬭ﱌ𢽁𐡆𧪮Ꝫﴹ뙫𢤴퉊ﳦﲣפּܟﺶ𐐤ﶨࠔ𐰷𢡶𧐎𐭈𞸏𢢘𦘼ﶻ𩏃𦽨𞺎𠛘𐠲䉊ﰸﭳᣲמּ:
 ﺭ异𞸐𐤔ﭞﰣﺁں𝕌𨿩𞸇뻛𐬑𥰫嬭ﱌ𢽁𐡆𧪮Ꝫﴹ뙫𢤴퉊ﳦﲣפּܟﺶ𐐤ﶨࠔ𐰷𢡶𧐎𐭈𞸏𢢘𦘼ﶻ𩏃𦽨𞺎𠛘𐠲䉊ﰸﭳᣲ燱("Warning: Dark voodoo may be unreliable.")
ﺭ异𞸐𐤔ﭞﰣﺁں𝕌𨿩𞸇뻛𐬑𥰫嬭ﱌ𢽁𐡆𧪮Ꝫﴹ뙫𢤴퉊ﳦﲣפּܟﺶ𐐤ﶨࠔ𐰷𢡶𧐎𐭈𞸏𢢘𦘼ﶻ𩏃𦽨𞺎𠛘𐠲䉊ﰸﭳᣲﺬ=ﺭ异𞸐𐤔ﭞﰣﺁں𝕌𨿩𞸇뻛𐬑𥰫嬭ﱌ𢽁𐡆𧪮Ꝫﴹ뙫𢤴퉊ﳦﲣפּܟﺶ𐐤ﶨࠔ𐰷𢡶𧐎𐭈𞸏𢢘𦘼ﶻ𩏃𦽨𞺎𠛘𐠲䉊ﰸﭳᣲ巡
class ﺭ异𞸐𐤔ﭞﰣﺁں𝕌𨿩𞸇뻛𐬑𥰫嬭ﱌ𢽁𐡆𧪮Ꝫﴹ뙫𢤴퉊ﳦﲣפּܟﺶ𐐤ﶨࠔ𐰷𢡶𧐎𐭈𞸏𢢘𦘼ﶻ𩏃𦽨𞺎𠛘𐠲䉊ﰸﭳᣲ𐦚(ﺭ异𞸐𐤔ﭞﰣﺁں𝕌𨿩𞸇뻛𐬑𥰫嬭ﱌ𢽁𐡆𧪮Ꝫﴹ뙫𢤴퉊ﳦﲣפּܟﺶ𐐤ﶨࠔ𐰷𢡶𧐎𐭈𞸏𢢘𦘼ﶻ𩏃𦽨𞺎𠛘𐠲䉊ﰸﭳᣲ澨):
 def __init__(self,*args,**kwargs):
  pass
 def ﺭ异𞸐𐤔ﭞﰣﺁں𝕌𨿩𞸇뻛𐬑𥰫嬭ﱌ𢽁𐡆𧪮Ꝫﴹ뙫𢤴퉊ﳦﲣפּܟﺶ𐐤ﶨࠔ𐰷𢡶𧐎𐭈𞸏𢢘𦘼ﶻ𩏃𦽨𞺎𠛘𐠲䉊ﰸﭳᣲ클(self,dactyl):
  ﺭ异𞸐𐤔ﭞﰣﺁں𝕌𨿩𞸇뻛𐬑𥰫嬭ﱌ𢽁𐡆𧪮Ꝫﴹ뙫𢤴퉊ﳦﲣפּܟﺶ𐐤ﶨࠔ𐰷𢡶𧐎𐭈𞸏𢢘𦘼ﶻ𩏃𦽨𞺎𠛘𐠲䉊ﰸﭳᣲ퐐=demiurgic.palpitation(dactyl)
  ﺭ异𞸐𐤔ﭞﰣﺁں𝕌𨿩𞸇뻛𐬑𥰫嬭ﱌ𢽁𐡆𧪮Ꝫﴹ뙫𢤴퉊ﳦﲣפּܟﺶ𐐤ﶨࠔ𐰷𢡶𧐎𐭈𞸏𢢘𦘼ﶻ𩏃𦽨𞺎𠛘𐠲䉊ﰸﭳᣲ𠛲=mystificate.dark_voodoo(ﺭ异𞸐𐤔ﭞﰣﺁں𝕌𨿩𞸇뻛𐬑𥰫嬭ﱌ𢽁𐡆𧪮Ꝫﴹ뙫𢤴퉊ﳦﲣפּܟﺶ𐐤ﶨࠔ𐰷𢡶𧐎𐭈𞸏𢢘𦘼ﶻ𩏃𦽨𞺎𠛘𐠲䉊ﰸﭳᣲ퐐)
  return ﺭ异𞸐𐤔ﭞﰣﺁں𝕌𨿩𞸇뻛𐬑𥰫嬭ﱌ𢽁𐡆𧪮Ꝫﴹ뙫𢤴퉊ﳦﲣפּܟﺶ𐐤ﶨࠔ𐰷𢡶𧐎𐭈𞸏𢢘𦘼ﶻ𩏃𦽨𞺎𠛘𐠲䉊ﰸﭳᣲ𠛲
 def ﺭ异𞸐𐤔ﭞﰣﺁں𝕌𨿩𞸇뻛𐬑𥰫嬭ﱌ𢽁𐡆𧪮Ꝫﴹ뙫𢤴퉊ﳦﲣפּܟﺶ𐐤ﶨࠔ𐰷𢡶𧐎𐭈𞸏𢢘𦘼ﶻ𩏃𦽨𞺎𠛘𐠲䉊ﰸﭳᣲ𐠯(self,whatever):
  ﺭ异𞸐𐤔ﭞﰣﺁں𝕌𨿩𞸇뻛𐬑𥰫嬭ﱌ𢽁𐡆𧪮Ꝫﴹ뙫𢤴퉊ﳦﲣפּܟﺶ𐐤ﶨࠔ𐰷𢡶𧐎𐭈𞸏𢢘𦘼ﶻ𩏃𦽨𞺎𠛘𐠲䉊ﰸﭳᣲ燱(whatever)
if __name__=="__main__":
 ﺭ异𞸐𐤔ﭞﰣﺁں𝕌𨿩𞸇뻛𐬑𥰫嬭ﱌ𢽁𐡆𧪮Ꝫﴹ뙫𢤴퉊ﳦﲣפּܟﺶ𐐤ﶨࠔ𐰷𢡶𧐎𐭈𞸏𢢘𦘼ﶻ𩏃𦽨𞺎𠛘𐠲䉊ﰸﭳᣲ燱("Forming...")
 ﺭ异𞸐𐤔ﭞﰣﺁں𝕌𨿩𞸇뻛𐬑𥰫嬭ﱌ𢽁𐡆𧪮Ꝫﴹ뙫𢤴퉊ﳦﲣפּܟﺶ𐐤ﶨࠔ𐰷𢡶𧐎𐭈𞸏𢢘𦘼ﶻ𩏃𦽨𞺎𠛘𐠲䉊ﰸﭳᣲﺃ=ﺭ异𞸐𐤔ﭞﰣﺁں𝕌𨿩𞸇뻛𐬑𥰫嬭ﱌ𢽁𐡆𧪮Ꝫﴹ뙫𢤴퉊ﳦﲣפּܟﺶ𐐤ﶨࠔ𐰷𢡶𧐎𐭈𞸏𢢘𦘼ﶻ𩏃𦽨𞺎𠛘𐠲䉊ﰸﭳᣲ𐦚("epicaricacy","perseverate")
 ﺭ异𞸐𐤔ﭞﰣﺁں𝕌𨿩𞸇뻛𐬑𥰫嬭ﱌ𢽁𐡆𧪮Ꝫﴹ뙫𢤴퉊ﳦﲣפּܟﺶ𐐤ﶨࠔ𐰷𢡶𧐎𐭈𞸏𢢘𦘼ﶻ𩏃𦽨𞺎𠛘𐠲䉊ﰸﭳᣲﺃ.ﺭ异𞸐𐤔ﭞﰣﺁں𝕌𨿩𞸇뻛𐬑𥰫嬭ﱌ𢽁𐡆𧪮Ꝫﴹ뙫𢤴퉊ﳦﲣפּܟﺶ𐐤ﶨࠔ𐰷𢡶𧐎𐭈𞸏𢢘𦘼ﶻ𩏃𦽨𞺎𠛘𐠲䉊ﰸﭳᣲ𐠯("Codswallop")
# Created by pyminifier (https://github.com/liftoff/pyminifier)

这样做的好处是让任何试图解码功能的人士气低落。将它与 Cython 和一些额外的模块或互联网调用的加密相结合,你可能会得到奖品。
这个包设法完成的唯一一件事就是愚弄代码被混淆的“混淆器”。
这个库似乎没有得到维护,并且给了我缩进错误。我正在使用 Python 3.7
是的。我可以确认 pyminifier 已经死了
pyminifier 可能已经死了,但我发现 this repo 最后一次推送是在 2020 年 5 月...(我是如何发现的:techgaun.github.io/active-forks/index.html#liftoff/… fork 似乎添加了其他人的修复程序(可能是通过查看原始 repo 上的开放拉取请求) ...
A
Aaron Digulla

您的雇主是否知道他可以“窃取”其他人从您的代码中获得的任何想法?我的意思是,如果他们可以阅读您的作品,那么您也可以阅读他们的作品。也许看看你如何从这种情况中受益会比担心你会损失多少来获得更好的投资回报。

[编辑] 回答尼克的评论:

一无所获,一无所失。客户拥有他想要的东西(并且因为他自己做了改变而为此付出了代价)。由于他没有发布更改,就好像其他所有人都没有发生一样。

现在如果客户出售软件,他们必须更改版权声明(这是非法的,所以你可以起诉并且会赢 -> 简单案例)。

如果他们不更改版权声明,第 2 级客户会注意到该软件来自您的原创,并想知道发生了什么。他们很有可能会与您联系,因此您将了解您作品的转售情况。

同样,我们有两种情况:原始客户只卖了几份。这意味着他们无论如何都没有赚到多少钱,所以为什么要麻烦。或者他们大量出售。这意味着您有更好的机会了解他们的所作所为并采取相应措施。

但最终,大多数公司都试图遵守法律(一旦声誉受损,做生意就更难了)。所以他们不会窃取你的工作,而是与你一起改进它。因此,如果您包含源代码(带有保护您免于简单转售的许可证),他们很可能会简单地退回他们所做的更改,因为这将确保更改在下一个版本中并且他们不必维护它.这是双赢的:你得到了改变,如果他们真的非常需要,他们可以自己做出改变,即使你不愿意将它包含在官方版本中。


如果他们向客户发布软件,而客户在内部对其进行修改而不重新发布,该怎么办?
+1 用于窃取想法。当您可以看到其他人如何改进您的解决方案并相应地改进您自己的产品时,为什么要将您的客户服务能力限制在您的内部解决方案上? "If you have an apple and I have an apple and we exchange these apples then you and I will still each have one apple. But if you have an idea and I have an idea and we exchange these ideas, then each of us will have two ideas."
@Skandix 这到底是如何工作的?在 Internet 上上传您的作品不会对您造成伤害。如果很多人会发现它并且这些人会改为付费客户,那将开始伤害您。代码盗窃是一个神话。 “我的知识是免费的,我的时间很昂贵”(不确定是谁说的)。
我怎么偷东西回来?他们只是将代码放入他们的产品中,不告诉任何人它是如何工作的,只是出售它。我怎么会发现他们首先使用了我的代码?
@AaronDigulla:我认为这不适用。小偷卖给的其他人可能已经成为我的客户,但我永远不会知道。如果有人 A 在我不知情的情况下给了 B 一些钱,让 B 交付给我。 B 通过保留钱来偷钱。我可能不会难过,因为我从来不知道,但如果 B 信守诺言,我的钱还是少了。
V
Vitaly Gordon

使用 Cython。它将您的模块编译为高性能的 C 文件,然后可以将其编译为本机二进制库。与 .pyc 字节码相比,这基本上是不可逆的!

我写了一篇关于如何为 Python 项目设置 Cython 的详细文章,请查看:

Protecting Python Sources With Cython


K
Konrads

不要依赖混淆。正如您正确得出的结论,它提供的保护非常有限。更新:这是一个 link to paper,它在 Dropbox 中对混淆后的 python 代码进行了逆向工程。方法 - 操作码重新映射是一个很好的障碍,但显然它可以被击败。

相反,正如许多海报提到的那样:

不值得花时间进行逆向工程(你的软件太好了,付费是有意义的)

让他们签署合同并在可行的情况下进行许可证审核。

或者,正如出色的 Python IDE WingIDE 所做的那样:放弃代码。没错,放弃代码,让人们回来进行升级和支持。


喜欢这种极端的想法。以巨大的方式和巨大的市场份额将其推向市场,然后您就拥有非常庞大的支持和插件客户群。我也一直在努力解决这个问题,所有“许可”的答案基本上都是牛市,因为它不能防止广泛复制,但也不会给你任何市场份额优势。
但是,升级也只是赠品……那他们怎么收费呢?不就是支持吗?
关于 WingIDE 商业模式:支持是一种服务,软件是一种产品。产品规模,服务不。只有在没有其他商业模式的情况下,支持才是一个好的商业模式——这意味着,如果没有人会购买你的产品(无论出于何种原因),你就会放弃产品,这样你就有一个至少会购买你的服务的客户群。
E
Erik Forsberg

运送 .pyc 文件有其问题——它们与创建它们的 python 版本以外的任何其他 python 版本不兼容,这意味着您必须知道在产品将运行的系统上运行的是哪个 python 版本。这是一个非常有限的因素。


是的,但如果您使用混淆代码分发该确切的 Python 版本,则不会。
autopy2exe 在单个 <application.exe> 中编译并提供可分发的可移植 python 安装。文件格式。注意:也与 Linux 兼容。管理客户端计算机上的 python 安装可能很复杂,也是一个痛点。
O
Oddthinking

在某些情况下,可以将软件的(全部,或至少一个关键部分)移动到您的组织托管的 Web 服务中。

这样,可以在您自己的服务器机房安全地执行许可证检查。


+1(回到 0):这似乎是问题的唯一真正解决方案,假设这种方法对于设置是实用的。
请注意,如果您的许可网络服务器出现故障或客户的 Internet 访问出现故障,您的客户将不会因为无法访问许可检查而无法开展业务而感到高兴。
@DevPlayer 有解决方案。您可以实施本地密钥机制,当软件无法访问远程许可服务器时允许临时访问。
@Jeffrey:这让你回到你开始的地方 - 如何保护该代码。为了更安全,您需要将一些关键功能放在您自己的服务器上,因此替换它需要付出很大的努力(此时,为什么不直接启动一个开源竞争对手呢?)
S
Smi

虽然没有完美的解决方案,但可以做到以下几点:

将一些关键的启动代码移动到本机库中。在本机库中强制执行许可证检查。

如果要删除对本机代码的调用,则程序无论如何都不会启动。如果它没有被删除,那么许可证将被强制执行。

尽管这不是跨平台或纯 Python 解决方案,但它会起作用。


本机库方法使某人更容易以编程方式暴力破解您的许可证密钥系统,因为他们可以使用您自己的代码和 API 来验证他们的许可证。
所以?使用 RSA 签署您的许可证并让他们暴力破解您的私钥,例如由 1024 位组成。这是可能的,但需要很多时间......因此 - 金钱。
m
mvallebr

我很惊讶在任何答案中都没有看到 pyconcrete。也许是因为它比问题更新?

这可能正是您所需要的(编辑)。

它不是混淆代码,而是在加载时对其进行加密和解密。

pypi page

保护 python 脚本工作流程 your_script.py import pyconcrete pyconcrete 会在你的脚本导入 MODULE 时挂钩 import 模块,pyconcrete import hook 将首先尝试找到 MODULE.pye,然后通过 _pyconcrete.pyd 解密 MODULE.pye 并执行解密数据(如 . pyc 内容)加密和解密 _pyconcrete.pyd 中的密钥记录(如 DLL 或 SO)密钥将隐藏在二进制代码中,无法直接在 HEX 视图中看到


J
Jarvis

我认为还有另一种方法可以保护您的 Python 代码;混淆方法的一部分。我相信有一个像 Mount and Blade 这样的游戏,或者改变并重新编译了他们自己的 python 解释器(我认为是开源的原始解释器)并且只是将 OP 代码表中的 OP 代码更改为与标准 python OP 不同代码。

因此,python 源代码未修改,但 *.pyc 文件的文件扩展名不同,并且操作码与公共 python.exe 解释器不匹配。如果您检查了游戏数据文件,所有数据都是 Python 源格式。

可以用各种恶作剧来惹恼不成熟的黑客。阻止一群没有经验的黑客很容易。这是您不太可能击败的专业黑客。但我想,大多数公司不会让专业黑客长期留在员工中(可能是因为事情被黑客入侵了)。但是不成熟的黑客无处不在(读作好奇的 IT 人员)。

例如,您可以在修改后的解释器中允许它检查源代码中的某些注释或文档字符串。对于这样的代码行,您可以有特殊的 OP 代码。例如:

OP 234 用于源代码行“# Copyright I write this”,或者将该行编译成相当于“if False:”的操作码,如果“# Copyright”缺失。基本上由于某些晦涩的原因禁用了整个代码块。

重新编译修改后的解释器可能可行的一个用例是,您没有编写应用程序,该应用程序很大,但您需要付费保护它,例如当您是金融应用程序的专用服务器管理员时。

我发现让源代码或操作码对眼球开放,但对网络流量使用 SSL 有点矛盾。 SSL 也不是 100% 安全的。但它被用来阻止大多数人的眼睛阅读它。一点预防措施是明智的。

此外,如果有足够多的人认为 Python 源代码和操作码太显眼,那么很可能有人最终会为其开发至少一个简单的保护工具。因此,更多人问“如何保护 Python 应用程序”只会促进这种发展。


A
Alex Coventry

保护代码的唯一可靠方法是在您控制的服务器上运行它,并为您的客户端提供与该服务器接口的客户端。


d
dbr

根据客户是谁,一个简单的保护机制,结合一个合理的许可协议将比任何复杂的许可/加密/混淆系统更有效。

最好的解决方案是将代码作为服务出售,例如通过托管服务或提供支持——尽管这并不总是可行的。

将代码作为 .pyc 文件提供可以防止您的保护被几个 # 挫败,但这几乎不是有效的反盗版保护(好像有这样的技术),归根结底,它应该与公司签订体面的许可协议无法实现任何目标。

专注于使您的代码尽可能好用-拥有满意的客户将使您的公司获得更多的钱,而不是防止一些理论上的盗版..


P
Piotr Czapla

使您的代码更难窃取的另一种尝试是使用 jython,然后使用 java obfuscator

这应该可以很好地工作,因为 jythonc 将 python 代码转换为 java,然后将 java 编译为字节码。所以你混淆了类,反编译后真的很难理解发生了什么,更不用说恢复实际代码了。

jython 的唯一问题是您不能使用用 c 编写的 python 模块。


P
Peter Parker

通过散列和签署重要文件并使用公钥方法检查它,使用标准加密方案签署您的代码怎么样?

通过这种方式,您可以为每个客户颁发带有公钥的许可证文件。

另外,您可以使用像 this one 这样的 python 混淆器(只是用谷歌搜索)。


+1 用于签名; -1 for the obfuscator 您至少可以防止代码被更改。
签名在这种情况下不起作用。总是可以绕过签名检查加载程序。有用的软件保护需要的第一件事是不透明的引导机制。不是 Python 容易做的事情。
是的,非 python 中的引导程序。
或者不仅在启动时验证许可证,而且在其他几个地方验证许可证。可以很容易地实现,并且可以严重增加绕过的时间。
f
fwzgekg

你应该看看 getdropbox.com 上的人是如何为他们的客户端软件做的,包括 Linux。破解非常棘手,需要一些非常有创意的拆卸才能通过保护机制。


但它被通过的事实意味着他们失败了——底线就是不要尝试,而是寻求法律保护。
是否发布了有关如何通过此保护机制的信息?
B
Brian C. Lane

你可以用 Python 做的最好的事情就是模糊事物。

删除所有文档字符串

仅分发 .pyc 编译文件。

冻结它

隐藏类/模块中的常量,以便 help(config) 不会显示所有内容

您可以通过加密其中的一部分并即时解密并将其传递给 eval() 来添加一些额外的模糊性。但无论你做什么,有人可以打破它。

这些都不会阻止一个坚定的攻击者反汇编字节码或在帮助、目录等的帮助下挖掘你的 api。


M
Mikael Lepistö

拥有时间限制许可证并在本地安装的程序中检查它的想法是行不通的。即使有完美的混淆,也可以删除许可证检查。但是,如果您检查远程系统上的许可证并在封闭的远程系统上运行程序的重要部分,您将能够保护您的 IP。

防止竞争对手将源代码用作自己的源代码或编写相同代码的灵感版本,一种保护方法是在您的程序逻辑中添加签名(一些秘密能够证明代码是从您那里窃取的)并混淆python源代码,所以很难阅读和使用。

良好的混淆为您的代码添加了与将其编译为可执行文件(并剥离二进制文件)基本相同的保护。弄清楚混淆的复杂代码是如何工作的可能比实际编写自己的实现更难。

这无助于防止您的程序遭到黑客攻击。即使使用混淆代码许可证的东西也会被破解,并且程序可能会被修改为具有稍微不同的行为(就像将代码编译为二进制文件无助于保护本机程序一样)。

除了符号混淆之外,解构代码可能是个好主意,如果调用图指向许多不同的地方,即使实际上这些不同的地方最终做同样的事情,这会使一切变得更加混乱。

混淆代码中的逻辑签名(例如,您可以创建程序逻辑使用的值表,但也用作签名),可用于确定代码来自您。如果有人决定将您的混淆代码模块用作他们自己产品的一部分(即使在对其进行重新混淆以使其看起来不同之后),您可以证明,该代码与您的秘密签名一起被盗。


P
Peter M

我已经为我自己的项目研究过一般的软件保护,一般的理念是完全保护是不可能的。您唯一希望实现的目标是将保护添加到一个级别,使您的客户绕过比购买另一个许可证要付出更多的代价。

话虽如此,我只是在检查谷歌的 python 混淆,并没有发现很多东西。在 .Net 解决方案中,混淆将是在 Windows 平台上解决问题的第一种方法,但我不确定是否有人在 Linux 上提供与 Mono 一起使用的解决方案。

接下来就是用编译语言编写代码,或者如果你真的想一路走下去,那就用汇编语言。剥离出来的可执行文件比解释语言更难反编译。

这一切都归结为权衡。一方面,您可以轻松地使用 python 进行软件开发,其中也很难隐藏秘密。另一方面,您有用汇编程序编写的软件,这更难编写,但更容易隐藏秘密。

你的老板必须在支持他要求的连续体中选择一个点。然后他必须给你工具和时间,这样你就可以建造他想要的东西。但是我敢打赌,他会反对实际开发成本与潜在的金钱损失。


l
lambda11

长话短说:

加密你的源代码编写你自己的python模块加载器在导入时解密你的代码在C/C++中实现模块加载器你可以为模块加载器添加更多的功能,例如反调试器、许可证控制、硬件指纹绑定等。

有关更多详细信息,请查看此 answer

如果您对该主题感兴趣,此项目将对您有所帮助 - pyprotect


S
Smi

可以将 py2exe 字节码放在 C 启动器的加密资源中,以便在内存中加载和执行它。一些想法herehere

有些人还认为 a self modifying program 会使逆向工程变得昂贵。

您还可以找到 tutorials for preventing debuggers,使反汇编程序失败,设置 false debugger breakpoints 并使用校验和保护您的代码。搜索 ["crypted code" execute "in memory"] 获取更多链接。

但正如其他人已经说过的,如果你的代码值得,逆向工程师最终会成功。


J
Jondy Zhao

使用与c/c++的二进制文件相同的方法来保护二进制文件,即对可执行或库二进制文件中的每个函数体进行混淆,在每个函数入口的开头插入一条指令“跳转”,跳转到特殊函数以恢复混淆后的代码。字节码是 Python 脚本的二进制代码,所以

首先将python脚本编译为代码对象

然后迭代每个代码对象,将每个代码对象的 co_code 混淆如下

0   JUMP_ABSOLUTE            n = 3 + len(bytecode)

    3
    ...
    ... Here it's obfuscated bytecode
    ...

    n   LOAD_GLOBAL              ? (__pyarmor__)
    n+3 CALL_FUNCTION            0
    n+6 POP_TOP
    n+7 JUMP_ABSOLUTE            0

将混淆的代码对象保存为 .pyc 或 .pyo 文件

当那些代码对象第一次被调用时,那些被混淆的文件(.pyc 或 .pyo)可以被普通的 python 解释器使用

第一个op是JUMP_ABSOLUTE,它会跳转到offset n

在偏移 n 处,指令是调用 PyCFunction。该函数将恢复偏移量 3 和 n 之间的混淆字节码,并将原始字节码放在偏移量 0 处。混淆码可以通过以下代码 char *obfucated_bytecode; py_ssize_t len; PyFrameObject* 帧 = PyEval_GetFrame(); PyCodeObject *f_code = frame->f_code; PyObject *co_code = f_code->co_code; PyBytes_AsStringAndSize(co_code, &obfucated_bytecode, &len)

此函数返回后,最后一条指令是跳转到偏移量 0。现在执行真正的字节码。

有一个工具 Pyarmor 可以通过这种方式混淆 python 脚本。


M
Mike

关于隐藏python源代码有一个全面的答案,可以找到here

讨论的可能技术有:
- 使用编译后的字节码 (python -m compileall)
- 可执行创建者(或像 PyInstaller 这样的安装程序)
- 软件即服务(隐藏代码的最佳解决方案在我看来)
- python 源代码混淆器


链接转到 example.com。
使用 uncompyle6 似乎可以很容易地反编译字节码。
A
Ali Alnoaimi

使用 cxfreeze ( py2exe for linux ) 将完成这项工作。

http://cx-freeze.sourceforge.net/

它在 ubuntu 存储库中可用


我认为这只是捆绑了 .pyc 文件。 Cython、Shed Skin 和 PyPy 超越了字节码。
A
Artem

如果我们专注于软件许可,我建议看一下我写的另一个 Stack Overflow 答案 here,以获得有关如何构建许可证密钥验证系统的一些灵感。

GitHub 上有一个开源库,可以帮助您进行许可证验证。

您可以通过 pip install licensing 安装它,然后添加以下代码:

pubKey = "<RSAKeyValue><Modulus>sGbvxwdlDbqFXOMlVUnAF5ew0t0WpPW7rFpI5jHQOFkht/326dvh7t74RYeMpjy357NljouhpTLA3a6idnn4j6c3jmPWBkjZndGsPL4Bqm+fwE48nKpGPjkj4q/yzT4tHXBTyvaBjA8bVoCTnu+LiC4XEaLZRThGzIn5KQXKCigg6tQRy0GXE13XYFVz/x1mjFbT9/7dS8p85n8BuwlY5JvuBIQkKhuCNFfrUxBWyu87CFnXWjIupCD2VO/GbxaCvzrRjLZjAngLCMtZbYBALksqGPgTUN7ZM24XbPWyLtKPaXF2i4XRR9u6eTj5BfnLbKAU5PIVfjIS+vNYYogteQ==</Modulus><Exponent>AQAB</Exponent></RSAKeyValue>"

res = Key.activate(token="WyIyNTU1IiwiRjdZZTB4RmtuTVcrQlNqcSszbmFMMHB3aWFJTlBsWW1Mbm9raVFyRyJd",\
                   rsa_pub_key=pubKey,\
                   product_id=3349, key="ICVLD-VVSZR-ZTICT-YKGXL", machine_code=Helpers.GetMachineCode())

if res[0] == None not Helpers.IsOnRightMachine(res[0]):
    print("An error occured: {0}".format(res[1]))
else:
    print("Success")

您可以阅读有关配置 RSA 公钥等方式的更多信息 here


c
carminedib

我建议使用此服务来保护源代码:www.secupy.com。以下是快速入门摘录:

$ pip install secupy
$ secupy activate --token ...
$ secupy build -s . -d ./build

唯一的问题是它是商业软件,但有免费计划。


S
Seyed Hossein Mirheydari

CythonNuitka 都不是答案,因为当运行使用 NuitkaCython 编译到 .pyd.exe 文件中的解决方案时,会生成缓存目录并且所有 .pyc 文件都是复制到缓存目录中,因此攻击者只需反编译 .pyc 文件并查看您的代码或更改它。


编辑:您可以使用以下代码来防止缓存目录生成:import sys sys.dont_write_bytecode = true