我正在尝试在Python
中编码Linux
脚本的内容。我刚开始使用一个简单的脚本test.py-
# !/app/logs/Python/bin/python3
# -*- coding: ascii -*-
print ("hi")
有了脚本后,我将执行vim -x test.py
并输入两次加密密钥。然后照常保存文件,然后使用python test.py
我尝试了链接here中提供的几乎所有示例,但仍然最终遇到以下错误-
SyntaxError: Non-ASCII character '\x97' in file test.py on line 1, but no encoding declared; see http://www.python.org/peps/pep-0263.html for details
我使用print sys.getdefaultencoding()
检查了默认编码,它是acsii。
我在这里想念什么。请澄清。我知道这个问题是重复的,但没有解决方案有帮助。
答案 0 :(得分:2)
Python知道如何执行明文Python源代码。如果对源文件进行加密,则该文件将不再包含有效的Python源,并且无法直接执行。
这里有2种可能的方法。首先是仅混淆您的来源。您应该意识到,混淆不是安全的,用户可以通过一些工作来恢复某些Python源(不一定是原始源,因为注释和doc字符串可能已被剥离,变量名可能已更改)。您可以阅读How do I protect Python code?和google上的 python obfuscate 来找到混淆Python源代码及其取舍的一些可能方法。
来源混乱的好消息是,任何人都可以使用,而无需任何密码。
第二种方法是加密源。如果您使用的是不错的工具,则可以假定在不知道密钥的情况下无法读取或执行文件。从这个意义上讲,vim
加密没有最高的声誉。以最简单的方式(例如,以您的示例vim -x
为例),您将必须解密文件才能执行它。不幸的是,标准的Python安装程序中没有提供好的加密模块,必须从pypi下载。众所周知的加密模块包括pycrypto和cryptography。
然后,您可以加密大部分代码,然后在运行时询问密钥,对其进行解密并执行。仍然是一项认真的工作,但可行。
或者,您可以使用另一种语言(C / C ++)构建一个解密器,该解密器将文件的其余部分解密并将其提供给python解释器,但是从功能上讲,这只是上述方法的一种变体。
根据您的评论,我假设您想在运行时对源代码进行加密并使用密码对其进行解密。主要原理是:
生成器可能是(此代码使用 cryptography 模块):
import cryptography.fernet
import cryptography.hazmat.primitives.kdf.pbkdf2
import cryptography.hazmat.primitives.hashes
import cryptography.hazmat.backends
import base64
import os
import sys
# the encryption function
def encrypt_source(infile, outfile, passwd):
with open(infile, 'rb') as fdin: # read original file
plain_data = fdin.read()
salt, key = gen_key(passwd) # derive a key from the password
f = cryptography.fernet.Fernet(key)
crypted_data = f.encrypt(plain_data) # encrypt the original code
with open(outfile, "w") as fdout: # prepend a decoding block
fdout.write("""#! /usr/bin/env python
import cryptography.fernet
import cryptography.hazmat.primitives.kdf.pbkdf2
import cryptography.hazmat.primitives.hashes
import cryptography.hazmat.backends
import base64
import os
def gen_key(passwd, salt): # key derivation
kdf = cryptography.hazmat.primitives.kdf.pbkdf2.PBKDF2HMAC(
algorithm = cryptography.hazmat.primitives.hashes.SHA256(),
length = 32,
salt = salt,
iterations = 100000,
backend = cryptography.hazmat.backends.default_backend()
)
return base64.urlsafe_b64encode(kdf.derive(passwd))
passwd = input("Password:") # ask for the password
salt = base64.decodebytes({})
key = gen_key(passwd.encode(), salt) # derive the key from the password and the original salt
crypted_source = base64.decodebytes( # decode (base64) the crypted source
b'''{}'''
)
f = cryptography.fernet.Fernet(key)
plain_source = f.decrypt(crypted_source) # decrypt it
exec(plain_source) # and exec it
""".format(base64.encodebytes(salt),
base64.encodebytes(crypted_data).decode()))
# derive a key from a password and a random salt
def gen_key(passwd, salt=None):
if salt is None: salt = os.urandom(16)
kdf = cryptography.hazmat.primitives.kdf.pbkdf2.PBKDF2HMAC(
algorithm = cryptography.hazmat.primitives.hashes.SHA256(),
length = 32,
salt = salt,
iterations = 100000,
backend = cryptography.hazmat.backends.default_backend()
)
return salt, base64.urlsafe_b64encode(kdf.derive(passwd))
if __name__ == '__main__':
if len(sys.argv) != 3:
print("Usage {} infile outfile".format(sys.argv[0]))
sys.exit(1)
passwd = input("Password:").encode() # ask for a password
encrypt_source(sys.argv[1], sys.argv[2], passwd) # and generates an encrypted Python script