我正在开发一个Python软件,将分发给我的雇主的客户.我的雇主希望使用时间限制的许可证文件来限制软件的使用.
如果我们分发.py文件甚至.pyc文件,那么很容易(反编译)删除检查许可文件的代码.
另一个方面是我的雇主不希望我们的客户阅读代码,担心代码可能被盗或至少是"新颖的想法".
有没有一个很好的方法来处理这个问题?优选使用现成的解决方案.
该软件将在Linux系统上运行(所以我认为py2exe不会这样做).
"有没有办法处理这个问题?" 没有.没有什么可以防止逆向工程.甚至DVD机器上的固件也经过逆向工程和AACS加密密钥暴露.尽管DMCA将其定为刑事犯罪,但这仍然存在.
由于没有技术方法可以阻止客户阅读您的代码,因此您必须应用普通的商业方法.
许可证.合同.条款和条件.即使人们可以阅读代码,这仍然有效.请注意,在使用这些组件销售软件之前,某些基于Python的组件可能要求您支付费用.此外,某些开源许可证禁止您隐藏该组件的来源或来源.
提供重要价值.如果你的东西是如此优秀 - 以难以拒绝的价格 - 没有动力浪费时间和金钱逆向工程.逆向工程很昂贵.使您的产品稍微便宜一点.
提供升级和增强功能,使任何逆向工程都成为一个坏主意.当下一个版本打破他们的逆向工程时,没有意义.这可以带到荒谬的极端,但是你应该提供新的功能,使下一个版本比逆向工程更有价值.
以极具吸引力的价格提供定制服务,他们宁愿付钱给您构建并支持增强功能.
使用过期的许可证密钥.这是残酷的,会给你一个坏名声,但它肯定会使你的软件停止工作.
将其作为Web服务提供.SaaS不涉及向客户下载.
Python是一种字节码编译的解释语言,很难锁定.即使您使用像py2exe这样的exe-packager ,可执行文件的布局也是众所周知的,并且Python字节码很容易理解.
通常在这种情况下,你必须做出权衡.保护代码真的有多重要?那里有真正的秘密(例如银行转账的对称加密密钥),还是你只是偏执狂?选择让您以最快的速度开发最佳产品的语言,并对您的新颖想法的价值有所了解.
如果您确定需要安全地执行许可证检查,请将其写为小型C扩展,以便许可证检查代码可以非常难(但并非不可能!)进行逆向工程,并将大部分代码保留在Python中.
您必须使用正确的工具来做正确的事情,并且Python不是设计为混淆的.恰恰相反; 一切都是开放的或易于在Python中显示或修改,因为这是语言的哲学.
如果您想要一些无法透视的东西,请寻找其他工具.这不是一件坏事,重要的是存在不同用途的几种不同工具.
混淆真的很难即使是已编译的程序也可以进行逆向工程,因此不要认为您可以完全保护任何代码.您可以分析混淆的PHP,打破闪存加密密钥等.每次都会破解新版本的Windows.
有法律要求是一个很好的方法您不能阻止某人滥用您的代码,但您可以轻松发现是否有人这样做.因此,这只是一个偶然的法律问题.
代码保护被高估了如今,商业模式倾向于销售服务而不是产品.你不能复制服务,盗版或盗取它.也许是时候考虑顺其自然了......
明智的想法:
使用Cython,Nuitka,Shed Skin或类似的东西将python编译为C代码,然后将您的应用程序分发为python二进制库(pyd).
这样,我认为没有任何Python(字节)代码,你已经做了任何合理数量的暗示,任何人(即你的雇主)都可以从常规代码中获得.(.NET或Java比这种情况更不安全,因为该字节码没有被混淆,可以相对容易地反编译成合理的源.)
Cython越来越与CPython兼容,所以我认为它应该可行.(我实际上是考虑到我们的产品..我们已经建立了一些第三方库作为pyd/dll,所以将我们自己的python代码作为二进制文件运送对我们来说并不是一个过分重要的步骤.)
有关如何操作的教程,请参阅此博客文章(不是我).(thx @hithwen)
疯狂的想法:
您可以让Cython单独为每个模块存储C文件,然后将它们全部连接起来并使用大量内联构建它们.这样,您的Python模块非常单一,并且难以使用常用工具进行芯片处理.
超越疯狂:
如果可以静态链接(并优化)python运行时和所有库(dll),则可以构建单个可执行文件.这样,拦截来自/来自python的调用以及你使用的任何框架库肯定是很困难的.如果您使用的是LGPL代码,则无法完成此操作.
我知道您希望您的客户使用python的强大功能,但不希望公开源代码.
以下是我的建议:
(a)将代码的关键部分写为C或C++库,然后使用SIP或swig将C/C++ API公开给Python命名空间.
(b)使用cython而不是Python
(c)在(a)和(b)中,应该可以使用Python接口将库分发为许可二进制文件.
您的雇主是否意识到他可以"窃取"其他人从您的代码中获得的任何想法?我的意思是,如果他们能读你的作品,他们也可以.也许看看如何从这种情况中获益将会产生更好的投资回报,而不是担心你会损失多少.
[编辑]回答尼克的评论:
什么都没有,没有任何损失.顾客拥有他想要的东西(并且因为他自己做了改变而付了钱).因为他没有发布变化,所以就好像它没有发生在其他人身上.
现在,如果客户出售软件,他们必须更改版权声明(这是非法的,所以你可以起诉并赢得 - >简单的案例).
如果他们不更改版权声明,二级客户会注意到该软件来自您的原始版本,并想知道发生了什么.他们可能会与您联系,因此您将了解到您的工作转售.
我们又有两个案例:原始客户只卖了几份.这意味着他们无论如何也赚不到多少钱,所以为什么要这么麻烦.或者他们批量出售.这意味着你有更好的机会了解他们做了什么并做了些什么.
但最终,大多数公司都试图遵守法律(一旦他们的声誉被破坏,做生意就更难).所以他们不会偷你的工作,而是和你一起改进它.因此,如果您包含源代码(具有保护您免受简单转售的许可证),他们可能会简单地推回他们所做的更改,因为这将确保更改在下一个版本中,并且他们不必维护它.这是双赢的:你会得到改变,即使你不愿意将它包括在正式版本中,他们也可以自己做出改变,如果他们真的迫切需要它.
你看过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)
不要依赖混淆.正如您已正确总结的那样,它提供的保护非常有限.更新:这是一个链接到纸张,在Dropbox中反向设计混淆的python代码.这种方法 - 操作码重新映射是一个很好的障碍,但很明显它可以被击败.
相反,正如许多海报所提到的那样:
不值得逆向工程时间(你的软件太好了,支付是有意义的)
让他们签订合同并在可行的情况下进行许可审核.
或者,正如kick-ass Python IDE WingIDE所做的那样:放弃代码.这是对的,给出代码并让人们回来升级和支持.
运送.pyc文件有其问题 - 它们与其创建的python版本不兼容任何其他python版本,这意味着您必须知道产品将在其上运行的系统上运行哪个python版本.这是一个非常有限的因素.
在某些情况下,可以将软件(全部或至少一个关键部分)移动到组织托管的Web服务中.
这样,可以在您自己的服务器机房的安全性下执行许可证检查.
使用Cython.它会将您的模块编译为高性能的C文件,然后可以将其编译为本机二进制库.与.pyc字节码相比,这基本上是不可逆的!
我已经写了一篇关于如何为Python项目设置Cython的详细文章,请查看:
使用Cython保护Python源代码
虽然没有完美的解决方案,但可以做到以下几点:
将一些关键的启动代码移动到本机库中.
在本机库中强制执行许可检查.
如果要删除对本机代码的调用,程序将无法启动.如果未删除,则将强制执行许可.
虽然这不是跨平台或纯Python解决方案,但它可以工作.
我认为还有一种方法可以保护您的Python代码; 混淆方法的一部分.我相信有一个像Mount和Blade这样的游戏或者改变并重新编译了他们自己的python解释器(我认为是开源的原始解释器)并且只是将OP代码表中的OP代码改为与标准python OP不同码.
所以python源是未修改的,但*.pyc文件的文件扩展名是不同的,操作码与公共python.exe解释器不匹配.如果您检查了游戏数据文件,则所有数据都是Python源格式.
可以通过这种方式解决各种不成熟的黑客问题.阻止一群没有经验的黑客很容易.这是你不可能击败的专业黑客.但是大多数公司并没有让我的黑客长期存在于我想象中(可能是因为事情被黑客入侵).但不成熟的黑客到处都是(读作好奇的IT员工).
例如,您可以在修改后的解释器中,允许它检查源中的某些注释或文档字符串.您可以为此类代码行提供特殊的OP代码.例如:
OP 234用于源代码行"#Ind rights I written this"或将该行编译成等同于"if False:"的操作码,如果缺少"#Popyright".基本上禁用整个代码块似乎是一些不明原因.
重新编译修改后的解释器可能是可行的一个用例是你没有编写应用程序,应用程序很大,但你需要付费才能保护它,例如当你是财务应用程序的专用服务器管理员时.
我发现将源或操作码保持为眼球开放有点矛盾,但使用SSL进行网络流量.SSL也不是100%安全的.但它用来阻止大多数人的眼睛阅读它.一点点预防措施是明智的.
此外,如果有足够多的人认为Python源代码和操作码太明显,那么最终可能会有人为它开发至少一个简单的保护工具.因此,越多人问"如何保护Python应用程序"只会促进这种发展.
保护代码的唯一可靠方法是在您控制的服务器上运行它,并为您的客户端提供与该服务器接口的客户端.
根据客户端是谁,一个简单的保护机制,以合理的许可协议相结合,将是远远超过任何复杂的许可/加密/模糊系统更有效.
最好的解决方案是将代码作为服务销售,比如通过托管服务或提供支持 - 尽管这并不总是实用的.
将代码作为.pyc
文件发送将会阻止您的保护被少数文件挫败#
,但它几乎没有有效的反盗版保护(就好像有这样的技术),并且在一天结束时,它不应该实现任何与公司签订合适的许可协议.
专注于使您的代码尽可能好用 - 拥有快乐的客户将使您的公司远远超过防止一些理论上的盗版.
在任何答案中都没有看到pyconcrete,我感到很惊讶.也许是因为它比问题更新?
它可能正是您所需要的(编辑).
它不是对代码进行模糊处理,而是在加载时对其进行加密和解密.
来自pypi页面:
保护python脚本工作流程
your_script.py
import pyconcrete
pyconcrete将挂钩导入模块
当你的脚本做进口
MODULE
,进口pyconcrete钩将试图找到MODULE.pye
,然后再解密MODULE.pye
通过_pyconcrete.pyd
并执行解密的数据(如.pyc文件内容)加密和解密秘密密钥记录
_pyconcrete.pyd
(如DLL或SO)密钥将隐藏在二进制代码中,在HEX视图中无法直接看到它
使代码更难窃取的另一种尝试是使用jython然后使用java混淆器.
这应该可以正常工作,因为jythonc将python代码转换为java,然后将java编译为字节码.所以,如果你对这些类进行模糊处理,那么在反编译后很难理解发生了什么,更不用说恢复实际的代码了.
jython的唯一问题是你不能使用用c编写的python模块.
你应该看看getdropbox.com的人是如何为他们的客户端软件做的,包括Linux.破解是非常棘手的,需要一些非常有创意的反汇编来克服保护机制.
如何使用标准加密方案通过散列和签名重要文件并使用公钥方法进行检查来签署代码?
通过这种方式,您可以为每个客户发布带有公钥的许可证文件.
另外你可以使用像这样的python混淆器(只是谷歌搜索它).
使用Python可以做的最好的事情就是模糊不清.
删除所有文档字符串
仅分发.pyc编译的文件.
冻结它
隐藏类/模块中的常量,以便help(config)不显示所有内容
您可以通过加密部分内容并在运行中解密并将其传递给eval()来添加一些额外的默认设置.但无论你做什么,都有人可以打破它.
这些都不会阻止坚定的攻击者通过帮助,dir等拆解字节码或挖掘你的api.
有时间限制许可证并在本地安装的程序中检查它的想法是行不通的.即使有完美的混淆,也可以删除许可证检查.但是,如果您检查远程系统上的许可证并在已关闭的远程系统上运行程序的重要部分,您将能够保护您的IP.
防止竞争对手使用源代码作为他们自己或编写相同代码的灵感版本,一种保护方法是向程序逻辑添加签名(一些秘密能够证明代码是从您那里窃取的)并混淆了python源代码所以,它很难阅读和利用.
良好的混淆为您的代码添加了基本相同的保护,将其编译为可执行文件(以及剥离二进制文件).弄清楚混淆的复杂代码如何工作可能比实际编写自己的实现更难.
这无助于防止您的程序被黑客攻击.即使使用混淆代码,许可证的内容也会被破解,程序可能会被修改为具有稍微不同的行为(与将代码编译为二进制文件无法帮助保护本机程序的方式相同).
除了符号混淆可能不好意思重构代码,如果例如调用图指向许多不同的地方,即使实际上那些不同的地方最终做同样的事情,也会使一切更加混乱.
混淆代码中的逻辑签名(例如,您可以创建程序逻辑使用的值表,但也可以用作签名),可用于确定代码源自您.如果某人决定使用您的混淆代码模块作为他们自己的产品的一部分(即使在重新混淆它以使其看起来不同之后),您可以显示,该代码被您的秘密签名窃取.