locker – Easy File Encryption

Provides functions to encrypt and decrypt files using AES cipher.

Tip

The name encryptor or something like that sounds more appropriate for the name of the module and the functions, but the damage is done already.

The Header

The header is used to store the important bits of data that will be used to identify and/or decrypt the encrypted file.

This is the structure of the header of an encrypted file:

Header Format (Big endian; 118 bytes)

Magic number (I)

Mode Value (H)

Nonce (16s)

Authentication Tag (32s)

Metadata (32s)

Key Derivation Function Salt (32s)

Note

The value in the brackets are the corresponding symbols used in struct module.

Parts of Header

The header can be represented as a C struct:

typedef struct {
    unsigned int magic;
    unsigned short mode;
    char nonce[16];
    char tag[32];
    char metadata[32];
    char salt[32];
} Header;
  • Magic number (unsigned int magic):

    A unique number to identify the filetype.

  • Mode value (unsigned short mode):

    The AES mode used to encrypt the file.

  • Nonce (char nonce[16]):

    The nonce or initialization vector used for the AES cipher.

  • Authentication Tag (char tag[32]):

    The tag generated by the cipher after the encryption is over.

  • Metadata (char metadata[32]):

    Any binary data. Only this can be specified by the user. The maximum possible length of the metadata is defined in MAX_METADATA_LEN.

  • Key Derivation Function Salt (char salt[32]):

    The salt used for key derivation.

Operation details

Password derivation

The password is first derived into a key with PBKDF2-HMAC with 32 byte salt, 150000 iterations, sha256 as the hash algorithm.

Cipher creation

The cipher is created with 12 byte nonce if mode is GCM else 16 byte nonce. The nonce is stored as a part of Header for identifying the file, along with other important values.

Authentication

Before the operation begins, the authentication data is passed to the cipher. The authentication bits are:

magic, mode, salt, metadata, nonce

in that order.

Finalization

After completion of the entire operation, the tag created by the authenticator of the cipher is written to the file as a part of Header. If the file is being decrypted, it is read from the Header for verifying the file integrity and correct decryption.

pyflocker.locker.KDFunc

A KDF callable

alias of Callable[[bytes, bytes, int], bytes]

pyflocker.locker.MAX_METADATA_LEN = 32

Maximum possible length of the metadata.

pyflocker.locker.MAX_TAG_LEN = 32

Maximum length of authentication tag.

pyflocker.locker.MAX_SALT_LEN = 32

Maximum length of password derivation salt.

pyflocker.locker.MAX_NONCE_LEN = 16

Maximum length of AES cipher’s nonce.

pyflocker.locker.HEADER_PAYLOAD = <_struct.Struct object>

A struct that represents the data that is written to the encrypted file as its header.

pyflocker.locker.AUTHENTICATION_PAYLOAD = <_struct.Struct object>

A struct that represents the data that is passed to the cipher’s authenticator.

pyflocker.locker.MAGIC = 3370462794

The magic number of the encrypted file.

pyflocker.locker.PBKDF2_HMAC(*, hash_name='sha256', password, salt, iterations=150000, dklen=None)

The default key derivation function. PBKDF2-HMAC-SHA256-150000 is used PyFLocker.

pyflocker.locker.METADATA = b'CREATED BY: PyFLocker'

The default metadata.

pyflocker.locker.EXTENSION = '.pyflk'

Default extension of the encrypted file.

pyflocker.locker.encryptf(infile: io.BufferedReader, outfile: IO[bytes], password: bytes, *, kdf: KDFunc | None = None, aes_mode: Modes = Modes.MODE_GCM, blocksize: int = 16384, metadata: bytes = b'CREATED BY: PyFLocker', dklen: int = 32, backend: Backends | None = None) None[source]

Encrypts the binary data using AES cipher and writes it to outfile.

Parameters:
  • infile – The binary stream to read from.

  • outfile – The binary stream to write the encrypted bytes into.

  • password – Password to use to encrypt the binary data.

Keyword Arguments:
  • kdf – The key derivation function to use. It must be a callable that accepts 3 keyword arguments: password, salt and dklen. If kdf is None, PBKDF2-HMAC-SHA256-150000 is used instead.

  • aes_mode – The AES mode to use for encryption/decryption. The mode can be any attribute from Modes except those which are defined in modes.SPECIAL. Defaults to Modes.MODE_GCM. The AES mode is stored as a part of the encrypted file.

  • blocksize – The amount of data to read from infile in each iteration. Defalts to 16384.

  • metadata – The metadata to write to the file. It must be up-to 32 bytes.

  • dklen – The desired key length (in bytes) for passing to the cipher. It specifies the strength of AES cipher. Defaults to 32.

  • backend – The backend to use to instantiate the AES cipher from. If None is specified (the default), any available backend will be used.

Raises:
pyflocker.locker.decryptf(infile: io.BufferedReader, outfile: IO[bytes], password: bytes, *, kdf: KDFunc | None = None, blocksize: int = 16384, metadata: bytes = b'CREATED BY: PyFLocker', dklen: int = 32, backend: Backends | None = None) None[source]

Decrypts the binary data using AES cipher and writes it to outfile.

Parameters:
  • infile – The binary stream to read from.

  • outfile – The binary stream to write the decrypted bytes into.

  • password – Password to use to decrypt the binary data.

Keyword Arguments:
  • kdf – The key derivation function to use. It must be a callable that accepts 3 keyword arguments: password, salt and dklen. If kdf is None, PBKDF2-HMAC-SHA256-150000 is used instead.

  • blocksize – The amount of data to read from infile in each iteration. Defalts to 16384.

  • metadata – The metadata to write to the file. It must be up-to 32 bytes.

  • dklen – The desired key length (in bytes) for passing to the cipher. It specifies the strength of AES cipher. Defaults to 32.

  • backend – The backend to use to instantiate the AES cipher from. If None is specified (the default), any available backend will be used.

Raises:
pyflocker.locker.encrypt(infile: str | PathLike, outfile: str | PathLike, password: bytes, remove: bool = True, **kwargs: Any) None[source]

Read from the file specified by the file-path infile and encrypt and write its contents to path specified by outfile.

Parameters:
  • infile – The file path to read the data from.

  • outfile – The file path to write the data to. The file should not already exist in the designated location.

  • password – Password to use to encrypt the file.

  • remove – Whether to remove the infile after it has been encrypted.

Keyword Arguments:

**kwargs – The addtional arguments to pass to encryptf. See the documentation of encryptf for more information.

Note

Any other errors are raised from the encryptf itself.

Important

The removal of file is NOT secure, because it uses os.remove() to remove the file. With enough expertise and time, the original file can be restored. If you want to remove the original file securely, consider using shred or srm or some other secure file deletion tools.

pyflocker.locker.decrypt(infile: str | PathLike, outfile: str | PathLike, password: bytes, remove: bool = True, **kwargs: Any) None[source]

Read from the file specified by the file-path infile and decrypt and write its contents to path specified by outfile.

Parameters:
  • infile – The file path to read the data from.

  • outfile – The file path to write the data to. The file should not already exist in the designated location.

  • password – Password to use to decrypt the file.

  • remove – Whether to remove the infile after it has been decrypted.

Keyword Arguments:

**kwargs – The addtional arguments to pass to decryptf. See the documentation of decryptf for more information.

Note

Any other errors are raised from the decryptf itself.

Important

The removal of file is NOT secure, because it uses os.remove() to remove the file. With enough expertise and time, the original file can be restored. If you want to remove the original file securely, consider using shred or srm or some other secure file deletion tools.

pyflocker.locker.lockerf(infile: io.BufferedReader, outfile: IO[bytes], password: bytes, encrypting: bool, **kwargs: Any) None[source]

Utility tool for encrypting files.

This function reads from infile in blocks, specified by blocksize, encrypts or decrypts the data and writes to outfile. By design of the cipher wrapper for R/W to files, no intermediate copy of data is made during operation.

Parameters:
  • infile – The binary stream to read from.

  • outfile – The binary stream to write the encrypted/decrypted bytes into.

  • password – Password to use to encrypt/decrypt the binary data.

  • encrypting – Whether the infile is being encrypted: True if encrypting else False.

Keyword Arguments:

**kwargs – The addtional arguments to pass to encryptf or decryptf. See their documentation more information.

Note

See documentation of encryptf and decryptf for possible errors.

pyflocker.locker.locker(file: str | PathLike[str], password: bytes, encrypting: bool | None = None, remove: bool = True, *, ext: str | None = None, newfile: str | PathLike[str] | None = None, **kwargs: Any) None[source]

Encrypts or decrypts files with AES algorithm.

Parameters:
  • file – The actual location of the file.

  • password – Password to use to encrypt/decrypt the file.

  • encrypting

    Whether the file is being locked (encrypted) or not.

    If encrypting is True, the file is encrypted no matter what the extension is. If encrypting is False, the file is decrypted no matter what the extension is.

    If encrypting is None (the default), it is guessed from the file extension and the file header instead.

    If encrypting is provided, argument ext is ignored.

  • remove – Whether to remove the file after encryption/decryption. Default is True.

Keyword Arguments:
  • ext – The extension to be used for the encrypted file. If None, the default value EXTENSION is used.

  • newfile – The name of the file to be created. It must not be already present. If None is provided (default), the name of the file plus the extension is used.

  • **kwargs – The addtional arguments to pass to encryptf or decryptf. See their documentation for more information.

Note

See documentation of encryptf and decryptf for possible errors.

Important

The removal of file is NOT secure, because it uses os.remove() to remove the file. With enough expertise and time, the original file can be restored. If you want to remove the original file securely, consider using shred or srm or some other secure file deletion tools.

pyflocker.locker.extract_header_from_file(path: str | PathLike, metadata: bytes = b'CREATED BY: PyFLocker') _Header[source]

Extract the header from the file file.

Parameters:
  • path – The path to the encrypted file.

  • metadata – The metadata written to the file as a part of the header.

Returns:

The header data.