![SOURCEdefender - advanced encryption protecting your Python codebase](https://images.sourcedefender.co.uk/logo.png "SOURCEdefender - advanced encryption protecting your python3 codebase")
- - -
[![python](https://shields.io/pypi/pyversions/sourcedefender)][python-url]
[![downloads](https://pepy.tech/badge/sourcedefender)][pepy-url]
[![downloads](https://pepy.tech/badge/sourcedefender/week)][pepy-url]

SOURCEdefender is the easiest way to obfuscate Python code using AES-256 encryption. AES is a symmetric algorithm which uses the same key for both encryption and decryption (the security of an AES system increases exponentially with key length). There is no impact on the performance of your running application as the decryption process takes place during the import of your module, so encrypted code won't run any slower once loaded from a _.pye_ file compared to loading from a _.py_ or _.pyc_ file.

# Features

- No end-user device licence required
- Symmetric AES 256-bit encryption
- FIPS 140-2 compliant cryptography
- Enforced expiry time on encrypted code
- Bundle encrypted files using PyInstaller

## Supported Environments

We support the following Operating System and architecture combinations and hook directly into the import process, so there are no cross-platform compatibility issues. Encrypted code will run on ___ANY___ other target using the same version of Python. For example, files encrypted in Windows using Python 3.7 will run with Python 3.7 on Linux.

| CPU Architecture | Operating System | Python Architecture | Python Versions |
| ---------------- | ---------------- | ------------------- | --------------- |
| AMD64            | Windows          | 64-bit              | 3.7 - 3.14      |
| x86_64           | Linux            | 64-bit              | 3.7 - 3.14      |
| x86_64           | macOS            | 64-bit              | 3.7 - 3.14      |
| ARM64            | macOS            | 64-bit              | 3.7 - 3.14      |
| AARCH64          | Linux            | 64-bit              | 3.7 - 3.14      |

# Trial Licence

The installation of SOURCEdefender will grant you a trial licence to encrypt files. This trial licence will only allow your script to work for a maximum of 24 hours; after that, it won't be usable. This is so you can test whether our solution is suitable for your needs. If you get stuck, then please [contact][sourcedefender-hello-email] us so we can help.

# Subscribe

To distribute encrypted code without limitation, you will need to create an [account][sourcedefender-dashboard] and set up your payment method. Once you have set up the account, you will be able to retrieve your activation token and use it to authorise your installation:

    $ sourcedefender activate --token 470a7f2e76ac11eb94390242ac130002
      SOURCEdefender

      Registration:

       - Account Status  : Active
       - Email Address   : hello@sourcedefender.co.uk
       - Account ID      : bfa41ccd-9738-33c0-83e9-cfa649c05288
       - System ID       : 7c9d-6ebb-5490-4e6f
       - Valid Until     : Sun, Apr 9, 2025 10:59 PM

Without activating your SDK, any encrypted code you create will only be usable for a maximum of __24hrs__. Access to our dashboard (via HTTPS) from your system is required so we can validate your account status.

If you want to view your activated licence status, you can use the __validate__ option:

    $ sourcedefender validate
      SOURCEdefender

      Registration:

       - Account Status  : Active
       - Email Address   : hello@sourcedefender.co.uk
       - Account ID      : bfa41ccd-9738-33c0-83e9-cfa649c05288
       - System ID       : 7c9d-6ebb-5490-4e6f
       - Valid Until     : Sun, Apr 9, 2025 10:59 PM
    $

If your licence is valid, this command will give the Exit Code (EC) of #0 (zero); otherwise, an invalid licence will be indicated by the EC of #1 (one). You should run this command after any automated build tasks to ensure you haven't created code with an unexpected 24-hour limitation.

## Price Plans

Our price plans are detailed on our [Dashboard][sourcedefender-dashboard]. If you do not see a price you like, please [email][sourcedefender-hello-email] us so we can discuss your situation and requirements.

# Usage

We have worked hard to ensure that the encryption/decryption process is as simple as possible. Here are a few examples of how it works and how to use the features provided. If you need advice on how to encrypt or import your code, please [contact][sourcedefender-hello-email] us for assistance.

### How do I protect my Python source code?

First, let's have a look at an example of the encryption process:

    $ cat /home/ubuntu/helloworld.py
    print("Hello World!")
    $

This is a very basic example, but we do not want anyone to get at our source code. We also don't want anyone to run this code after 1 hour so when we encrypt the file we can enforce an expiry time of 1 hour from now with the __--ttl__ option, and we can delete the plaintext .py file after encryption by adding the __--remove__ option.

The command would look like this:

    $ sourcedefender encrypt --remove --ttl=1h /home/ubuntu/helloworld.py
    SOURCEdefender

    Processing:

    /home/ubuntu/helloworld.py

    $

The TTL argument offers the following options: weeks(w), days(d), hours(h), minutes(m), and seconds(s).
Usage is for example: --ttl=10s, or --ttl=24m, or --ttl=1m, or just --ttl=3600. This can't be changed after encryption.

The '--remove' option deletes the original .py file. Make sure you use this so you don't accidentally distribute the plain-text code. Now the file is encrypted, its contents are as follows:

    $ cat /home/ubuntu/helloworld.pye
    ---BEGIN PYE FILE---
    5987175C5B1FD58E1123C378299C8A7B705D25A3
    70ED07D971D6DE1E07A1BFC6EBDA44BF038B80C3
    8B855DDB9144894ED0A69DA15C05B47DFB683671
    2904304AD56755B4F6EA324BC022BFF091A27662
    0B39CD3952CC1897A53AE988A40AD17A0D8D5142
    5E133A49CC1D37767714CF9AADDB7B79D4E79524
    790EFC4D7D27380EE4A14B406E2D1822C2856803
    13C4
    ----END PYE FILE----
    $

Once a file has been encrypted, its new extension is __.pye__ so our loader can identify encrypted files. All you need to remember is to include __sourcedefender__ as a Python dependency while packaging your project and import the sourcedefender module before you attempt to import and use your encrypted code.

### Importing packages & modules

The usual import system can still be used, and you can import encrypted code from within encrypted code, so you don't need to do anything special with your import statements.

    $ cd /home/ubuntu
    $ ls
    helloworld.pye
    $ python3
    >>>
    >>> import sourcedefender
    >>> import helloworld
    Hello World!
    >>> exit()
    $

### Using your own password for encryption

It's easy to use your own encryption password. If you do not set this, we generate unique ones for each file you encrypt. Our passwords are more secure, but should you wish to set your own, these can be set from a command option:

    sourcedefender encrypt --password 1234abcd mycode.py

or as an Environment variable:

    export SOURCEDEFENDER_PASSWORD="1234abcd"
    sourcedefender encrypt mycode.py

To import the code, you can set an environment variable (as with the encryption process). You can also set these in your code before the import:

    $ python3
    >>> import sourcedefender
    >>> from os import environ
    >>> environ["SOURCEDEFENDER_PASSWORD"] = "1234abcd"
    >>> import mycode

The password is applicable to the next import, so if you want different ones for different files, feel free to encrypt with different values.


### How do shebangs work with encrypted files?

You can add a shebang to encrypted `.pye` files to make them directly executable. The shebang must be the first line of the file, followed by the encrypted content.

**Important**: Normal Python imports (`import module`) always require the `.pye` extension. Files without extension are only recognized when executed directly (via `./script` or `sourcedefender script`), not when imported.

Here's an example. First, encrypt a file:

    $ cat echo.py
    print("echo")
    print("Name:", __name__)
    $ sourcedefender encrypt echo.py --remove
    $ sed -i '1i#!/usr/bin/env sourcedefender' echo.pye
    $ chmod +x echo.pye
    $ cat echo.pye
    #!/usr/bin/env sourcedefender
    ---BEGIN PYE FILE---
    6985734F001BBC43A8224531ACCE3CD69D337A23
    56EAF562F212CCCD390153686EDC333D4A03DD89
    13BE9D8DA23E150FECBE5E1820FFEB6FF8ED52BB
    B0C9001ABEAF1F6572C52B5D9B1996003F7469C4
    2F95AEED9138AA445012BF23C710DB04CB6B2EC3
    0B819033766AAE643ABC40555ADA556B1B86ED23
    2C560D28D073D0B46A8F058BFFFD1653B919BA21
    E078EDF8211BCFFC95DF2B4F76967014C54731D7
    EAD9
    ----END PYE FILE----
    $ ./echo.pye
    echo
    Name: __main__
    $

**Removing the `.pye` extension**: If you want to create a script without the `.pye` extension, you can copy the shebang-enabled `.pye` file to a file without the extension. **Important**: Encryption is tied to the filename, so the file without extension must have the same base name as the original encrypted file. For example, if you encrypted `echo.py` to create `echo.pye`, you can create `echo` (without extension) from `echo.pye`, but you cannot rename it to a different name. The encryption password is derived from the filename, so renaming encrypted files will break decryption.

### Integrating encrypted code with PyInstaller

PyInstaller scans your plain-text code for import statements so it knows what packages to freeze. This scanning is not possible inside encrypted code, so we have created a 'pack' command to help. However, you will need to ask PyInstaller to include any hidden libs by using the '--hidden-import' or '--add-binary' options.

We are unable to guess what parts of your code you want to encrypt. If you encrypt all your code, sometimes that stops Python from working. So, with that in mind, please ensure you encrypt your code before using the pack command.

For this example, we have the following project structure:

    pyexe.py
    lib
    └── helloworld.pye

In our pyexe script, we have the following code:

    $ cat pyexe.py
    import helloworld

To ensure that PyInstaller includes our encrypted files, we need to tell it where they are with the --add-binary option. So, for the above project, we could use this command:

    sourcedefender encrypt pyexe.py --remove
    sourcedefender pack pyexe.pye -- --add-binary $(pwd)/lib:.

There is a strange quirk with PyInstaller that we haven't yet found a workaround for. When you include extra args after '--', you need to provide full paths of the source folders otherwise, you will get a tmp folder not found error such as this:

    Unable to find "/tmp/tmpp9pt6l97/lib" when adding binary and data files.

### Integrating encrypted code with Django

You can encrypt your Django project just the same as you can any other Python code. Don't forget to include "import sourcedefender" in the ``__init__.py`` file that is in the same directory as your settings.py file. Only obfuscate your own code and not code generated by the Django commands. There is no point in protecting files such as urls.py as these should not contain much/any of your own code other than things that have been imported.

### requirements.txt

Because we only keep the last available version of a branch online, you can lock your version to a branch by including this in your requirements.txt file:

    sourcedefender~=16.0

This will install the latest release >= 16.0.0 but less than 17.0.0, so major branch updates will need to be completed manually.


We always endeavour to keep the latest release of a branch on PyPi but there may be some reasons that we need to remove all older versions. You should always attempt to cache/mirror our SDK, please take a look at the [unearth][pypi-unearth] package which will give you a URL for the tar.gz file.

# Legal

THE SOFTWARE IS PROVIDED "AS IS," AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. REVERSE ENGINEERING IS STRICTLY PROHIBITED.

##### __Copyright © 2018-2025 SOURCEdefender. All rights reserved.__

<!-- URLs -->
[python-url]: https://www.python.org
[pepy-url]: https://pepy.tech/project/sourcedefender
[pypi-url]: https://pypi.org/project/sourcedefender
[sourcedefender-hello-email]: mailto:hello@sourcedefender.co.uk
[sourcedefender-dashboard]: https://dashboard.sourcedefender.co.uk/signup?src=pypi-readme
[pypi-unearth]: https://pypi.org/project/unearth
