Listing importpyepy Importsencrypted Python modules

import imputil, rotor, os, marshal

SECRET_CODE = 'bitakhon'

rot = rotor.newrotor(SECRET_CODE)

def encrypt(name):

# Compiles and encrypts a Python file data = compile(open(name).read(), name, 'exec')

base, ext = os.path.splitext(name) data = rot.encrypt(marshal.dumps(data)) open(base+'.pye', 'wb').write(data)

def handle_pye(fullpath, fileinfo, name):

# Print a debugging message print 'Importing "%s" from "%s"' % (name,fullpath)

data = marshal.load(fullpath) return 0, rot.decrypt(data),{}

im = imputil.ImportManager()

im.add_suffix('.pye',handle_pye)

im.install()

To test it, rename stuff.pye to just stuff.py (or use any other Python source file) and use the encrypt function to create a .pye file:

>>> import importpye

Now you can distribute the stuff.pye file, and programs can load it without needing to handle the details of decryption:

>>> import importpye >>> import stuff I am being imported! >>> stuff.a, stuff.b (10, 'Hello')

With a little extra work, you can use this method to distribute Python modules whose contents are relatively secure. Using the Python/C API, you can create a small C program that embeds the Python interpreter and takes care of setting up the rotor (or whatever other decryption engine you use) so that it's not overly trivial for someone else to decrypt the files. Furthermore, by not advertising the fact that your program is actually Python, and by grouping all the modules together into a single archive file (perhaps as a pickled dictionary), you can prevent all but the nosiest of people from obtaining your program source.

Chapters 29 and 30 cover extending and embedding Python with C, and Chapter 12 teaches you how to serialize Python objects using the pickle and marshal modules.

0 0

Post a comment