Make your python script SAFETY
Background
We know when we run Python script we can get the .pyc
files. But there are some tools that can decompile .pyc
files to .py
files. It is not a good behavior but in China, a lot of people are using it.
How to make your python script safety ?
I want to invent a new kind of file pye
. pye
is safety than .pyc
file. We can use AES to encrypt the .pyc
file to .pye
file. And when we run .pye
file, we can use AES to decrypt the .pye
file to .pyc
file. The AES key should be store safety. We can use pye
to make your python script safety.
Here is the code to encrypt pyc
to pye
:
import os
from Crypto.Cipher import AES
from Crypto.Util.Padding import pad, unpad
from Crypto.Random import get_random_bytes
# generate a random key
key = get_random_bytes(32) # AES-256
# encrypt pyc to pye
def encrypt_pyc_to_pye(input_file, output_file, key):
cipher = AES.new(key, AES.MODE_CBC)
with open(input_file, 'rb') as f:
data = f.read()
encrypted_data = cipher.encrypt(pad(data, AES.block_size))
with open(output_file, 'wb') as f:
f.write(cipher.iv)
f.write(encrypted_data)
# example
encrypt_pyc_to_pye('example.pyc', 'example.pye', key)
# decrypt pye to pyc
def decrypt_pye_to_pyc(input_file, output_file, key):
with open(input_file, 'rb') as f:
iv = f.read(AES.block_size)
encrypted_data = f.read()
cipher = AES.new(key, AES.MODE_CBC, iv)
decrypted_data = unpad(cipher.decrypt(encrypted_data), AES.block_size)
with open(output_file, 'wb') as f:
f.write(decrypted_data)
# example
decrypt_pye_to_pyc('example.pye', 'example.pyc', key)
# run example.py
os.system('python -m example')
Let’s make the test. First install uncompyle6.
pip install uncompyle6
Write the example.py
: (Anything is okay!)
print("Hello World!")
Get the .pyc
file:
import py_compile
py_compile.compile('example.py', 'example.pyc')
Let’s uncrypted .pyc
file, we can get the source code. (You can use uncompyle6
to decompile .pyc
file or you can use some websites like pydecompile
)
If we use .pyc
, we can get the source code. But what about .pye
? NOTHING!
Now we can make sure .pye
is safe. We can make it more safe by using asymmetric encryption. But it may cost some times.
Here is the code to encrypt pyc
to pye
using asymmetric encryption:
import os
from Crypto.Cipher import AES
from Crypto.Util.Padding import pad, unpad
from Crypto.Random import get_random_bytes
from Crypto.Hash import HMAC, SHA256
key = get_random_bytes(32) # AES-256
hmac_key = get_random_bytes(32) # HMAC-SHA256
# write keys to file
def write_keys_to_file(key, hmac_key):
with open('.keys', 'wb') as f:
f.write(key)
f.write(hmac_key)
write_keys_to_file(key, hmac_key)
# pyc to pye
def encrypt_pyc_to_pye(input_file, output_file, key, hmac_key):
cipher = AES.new(key, AES.MODE_CBC)
with open(input_file, 'rb') as f:
data = f.read()
encrypted_data = cipher.encrypt(pad(data, AES.block_size))
# calculate hmac
hmac = HMAC.new(hmac_key, digestmod=SHA256)
hmac.update(encrypted_data)
hmac_value = hmac.digest()
with open(output_file, 'wb') as f:
f.write(cipher.iv)
f.write(encrypted_data)
f.write(hmac_value)
encrypt_pyc_to_pye('example.pyc', 'example.pye', key, hmac_key)
Decrypt pye
to pyc
:
import os
from Crypto.Cipher import AES
from Crypto.Util.Padding import pad, unpad
from Crypto.Hash import HMAC, SHA256
# read keys from file
def read_keys_from_file():
with open('.keys', 'rb') as f:
key = f.read(32)
hmac_key = f.read(32)
return key, hmac_key
# decrypt pye to pyc
def decrypt_pye_to_pyc(input_file, output_file, key, hmac_key):
with open(input_file, 'rb') as f:
iv = f.read(AES.block_size) # read iv
encrypted_data = f.read(-32) # read encrypted data
hmac_value = f.read(32) # read hmac
hmac = HMAC.new(hmac_key, digestmod=SHA256)
hmac.update(encrypted_data)
if not hmac.verify(hmac_value):
raise ValueError("HMAC verification failed")
cipher = AES.new(key, AES.MODE_CBC, iv=iv)
decrypted_data = unpad(cipher.decrypt(encrypted_data), AES.block_size)
with open(output_file, 'wb') as f:
f.write(decrypted_data)
key, hmac_key = read_keys_from_file()
decrypt_pye_to_pyc('example.pye', 'example.pyc', key, hmac_key)
This kind of way is more safe than .pyc
file. But it may cost some times.
Conclusion
We can make our python script safety by using pye
. It is more safe than .pyc
file. But it may cost some times. If you do not need high safety, AES is enough. But if you need high safety, you can use asymmetric encryption such as RSA.
End
This is my second discuss. I am not good at English. I am sorry for that. Say what you want to say !! (Bug report & fix, Better soultion, Idea, etc.)