Metadata-Version: 2.4 Name: aesfile Version: 0.0.6 Summary: A python xxxFile like ( ie GzipFile, BZ2File, ...) for manipulating AES encrypted files. Project-URL: HomePage, https://github.com/bibi21000/AesFile Project-URL: Issues, https://github.com/bibi21000/AesFile/issues Project-URL: Changelog, https://github.com/bibi21000/AesFile/blob/master/CHANGELOG.md Project-URL: Documentation, https://bibi21000.github.io/AesFile/ Author-email: bibi21000 Maintainer-email: bibi21000 License-File: LICENSE Classifier: Development Status :: 4 - Beta Classifier: Intended Audience :: Developers Classifier: License :: OSI Approved :: MIT License Classifier: Operating System :: OS Independent Classifier: Programming Language :: Python :: 3 Classifier: Programming Language :: Python :: 3.9 Classifier: Programming Language :: Python :: 3.10 Classifier: Programming Language :: Python :: 3.11 Classifier: Programming Language :: Python :: 3.12 Classifier: Topic :: Software Development :: Libraries :: Python Modules Requires-Python: >=3.9 Requires-Dist: cofferfile Requires-Dist: pycryptodome Provides-Extra: build Requires-Dist: build; extra == 'build' Requires-Dist: twine; extra == 'build' Provides-Extra: doc Requires-Dist: pdoc; extra == 'doc' Provides-Extra: test Requires-Dist: bandit; extra == 'test' Requires-Dist: coverage[toml]; extra == 'test' Requires-Dist: pytest; extra == 'test' Requires-Dist: pytest-cov; extra == 'test' Requires-Dist: pytest-mock; extra == 'test' Requires-Dist: pytest-random-order; extra == 'test' Requires-Dist: pytest-xdist; extra == 'test' Requires-Dist: ruff; extra == 'test' Provides-Extra: zstd Requires-Dist: pyzstd; extra == 'zstd' Description-Content-Type: text/markdown [![CircleCI](https://dl.circleci.com/status-badge/img/gh/bibi21000/AesFile/tree/main.svg?style=shield)](https://dl.circleci.com/status-badge/redirect/gh/bibi21000/AesFile/tree/main) [![CodeQL](https://github.com/bibi21000/AesFile/actions/workflows/codeql.yml/badge.svg)](https://github.com/bibi21000/AesFile/actions/workflows/codeql.yml) [![codecov](https://codecov.io/gh/bibi21000/AesFile/graph/badge.svg?token=4124GIOJAK)](https://codecov.io/gh/bibi21000/AesFile) [![PyPI - Downloads](https://img.shields.io/pypi/dm/aesfile)](https://pypi.org/project/aesfile/) # AesFile A python xxxFile like (ie TarFile, GzipFile, BZ2File, pyzstd.ZstdFile, ...) for encrypting files with cryptography AES. This project is part of the CofferFile : https://github.com/bibi21000/CofferFile If you're looking for a more powerfull storage for your sensible datas, look at PyCoffer : https://github.com/bibi21000/PyCoffer. ## Install ``` pip install aesfile ``` ## Create your encryption key ``` from Crypto.Random import get_random_bytes key = get_random_bytes(16) ``` and store it in a safe place (disk, database, ...). This key is essential to encrypt and decrypt data. Losing this key means losing the data. ## "open" your encrypted files like normal files Text files : ``` import aesfile with aesfile.open('test.txc', mode='wt', aes_key=key, encoding="utf-8") as ff: ff.write(data) with aesfile.open('test.txc', "rt", aes_key=key, encoding="utf-8") as ff: data = ff.read() with aesfile.open('test.txc', mode='wt', aes_key=key, encoding="utf-8") as ff: ff.writelines(data) with aesfile.open('test.txc', "rt", aes_key=key, encoding="utf-8") as ff: data = ff.readlines() ``` Binary files : ``` import aesfile with aesfile.open('test.dac', mode='wb', aes_key=key) as ff: ff.write(data) with aesfile.open('test.dac', "rb", aes_key=key) as ff: data = ff.read() ``` ## Or compress and crypt them with pyzstd Look at https://github.com/bibi21000/CofferFile/blob/main/BENCHMARK.md. ``` pip install aesfile[zstd] ``` ``` from aesfile.zstd import AesFile with AesFile('test.dac', mode='wb', aes_key=key) as ff: ff.write(data) with AesFile('test.dac', mode='rb', aes_key=key) as ff: data = ff.read() ``` ## And chain it to tar and bz2 ``` class TarBz2AesFile(tarfile.TarFile): def __init__(self, name, mode='r', aes_key=None, chunk_size=aesfile.CHUNK_SIZE, **kwargs): compresslevel = kwargs.pop('compresslevel', 9) self.fernet_file = aesfile.AesFile(name, mode, aes_key=aes_key, chunk_size=chunk_size, **kwargs) try: self.bz2_file = bz2.BZ2File(self.fernet_file, mode=mode, compresslevel=compresslevel, **kwargs) try: super().__init__(fileobj=self.bz2_file, mode=mode, **kwargs) except Exception: self.bz2_file.close() raise except Exception: self.fernet_file.close() raise def close(self): try: super().close() finally: try: if self.fernet_file is not None: self.bz2_file.close() finally: if self.fernet_file is not None: self.fernet_file.close() with TarBz2AesFile('test.zsc', mode='wb', aes_key=key) as ff: ff.add(dataf1, 'file1.out') ff.add(dataf2, 'file2.out') with TarBz2AesFile('test.zsc', mode='rb', aes_key=key) as ff: fdata1 = ff.extractfile('file1.out') fdata2 = ff.extractfile('file2.out') ``` ## Encrypt / decrypt existing files Encrypt : ``` import aesfile with open(source, 'rb') as fin, aesfile.open(destination, mode='wb', aes_key=key) as fout: while True: data = fin.read(7777) if not data: break fout.write(data) ``` Decrypt : ``` import aesfile with aesfile.open(source, mode='rb', aes_key=key) as fin, open(destination, 'wb') as fout : while True: data = fin.read(8888) if not data: break fout.write(data) ``` Or to compress and crypt ``` import aesfile.zstd with open(source, 'rb') as fin, aesfile.zstd.open(destination, mode='wb', aes_key=key) as fout: while True: data = fin.read(7777) if not data: break fout.write(data) with aesfile.zstd.open(source, mode='rb', aes_key=key) as fin, open(destination, 'wb') as fout : while True: data = fin.read(8888) if not data: break fout.write(data) ``` Look at documentation : https://bibi21000.github.io/AesFile/