我正在用Python开发一款软件,它将分发给我雇主的客户。我的雇主想用一个有时间限制的许可证文件来限制软件的使用。
如果我们分发.py文件甚至.pyc文件,将很容易(反编译和)删除检查许可证文件的代码。
另一个方面是,我的雇主不希望我们的客户读到代码,担心代码可能被窃取,或者至少是“新颖的想法”。
有什么好办法来解决这个问题吗?
我正在用Python开发一款软件,它将分发给我雇主的客户。我的雇主想用一个有时间限制的许可证文件来限制软件的使用。
如果我们分发.py文件甚至.pyc文件,将很容易(反编译和)删除检查许可证文件的代码。
另一个方面是,我的雇主不希望我们的客户读到代码,担心代码可能被窃取,或者至少是“新颖的想法”。
有什么好办法来解决这个问题吗?
当前回答
如果我们关注软件许可,我建议看看我在这里写的另一个Stack Overflow答案,以获得如何构建许可密钥验证系统的灵感。
GitHub上有一个开源库,可以帮助您进行许可证验证。
你可以通过pip安装许可来安装它,然后添加以下代码:
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公钥等配置方式的信息。
其他回答
另一种让代码更难被窃取的方法是使用jython,然后使用java混淆器。
这应该工作得很好,因为jythonc将python代码转换为java,然后将java编译为字节码。因此,如果混淆了类,就很难理解反编译后会发生什么,更不用说恢复实际的代码了。
jython的唯一问题是你不能使用用c编写的python模块。
你应该看看getdropbox.com的人是如何为他们的客户端软件(包括Linux)做这件事的。这是相当棘手的破解,需要一些相当有创意的拆卸来通过保护机制。
用同样的方法保护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解释器使用,当这些代码对象第一次被调用时
First op is JUMP_ABSOLUTE, it will jump to offset n At offset n, the instruction is to call a PyCFunction. This function will restore those obfuscated bytecode between offset 3 and n, and put the original byte-code at offset 0. The obfuscated code can be got by the following code char *obfucated_bytecode; Py_ssize_t len; PyFrameObject* frame = PyEval_GetFrame(); PyCodeObject *f_code = frame->f_code; PyObject *co_code = f_code->co_code; PyBytes_AsStringAndSize(co_code, &obfucated_bytecode, &len) After this function returns, the last instruction is to jump to offset 0. The really byte-code now is executed.
有一个工具Pyarmor可以通过这种方式混淆python脚本。
“有没有解决这个问题的好办法?”不。没有什么可以防止逆向工程。甚至DVD机器上的固件也被逆向工程,AACS加密密钥被暴露。这还是不顾DMCA规定的刑事犯罪。
由于没有任何技术方法可以阻止客户阅读您的代码,所以您必须应用普通的商业方法。
Licenses. Contracts. Terms and Conditions. This still works even when people can read the code. Note that some of your Python-based components may require that you pay fees before you sell software using those components. Also, some open-source licenses prohibit you from concealing the source or origins of that component. Offer significant value. If your stuff is so good -- at a price that is hard to refuse -- there's no incentive to waste time and money reverse engineering anything. Reverse engineering is expensive. Make your product slightly less expensive. Offer upgrades and enhancements that make any reverse engineering a bad idea. When the next release breaks their reverse engineering, there's no point. This can be carried to absurd extremes, but you should offer new features that make the next release more valuable than reverse engineering. Offer customization at rates so attractive that they'd rather pay you to build and support the enhancements. Use a license key which expires. This is cruel, and will give you a bad reputation, but it certainly makes your software stop working. Offer it as a web service. SaaS involves no downloads to customers.
Python是一种字节码编译的解释型语言,很难被锁定。即使您使用py2exe这样的exe-packager,可执行文件的布局也是众所周知的,Python字节码也很好理解。
通常在这种情况下,你必须做出权衡。保护代码到底有多重要?里面有真正的秘密吗(比如对称加密银行转账的密钥),还是你只是多疑了?选择能让你最快开发出最好产品的语言,并现实地看待你的新想法的价值。
如果您决定确实需要安全地执行许可检查,可以将其编写为一个小的C扩展,这样许可证检查代码就很难(但不是不可能!)进行反向工程,并将大部分代码留在Python中。