ORIGINAL POST 03.19.2022
Here is one way to accomplish your use case using pyzipper
import fs
import pyzipper
# create in-memory file system
mem_fs = fs.open_fs('mem://')
mem_fs.makedir('hidden_dir')
# generate data
data = b'ab' * 10
secret_password = b'super secret password'
# Create encrypted password protected ZIP file in-memory
with pyzipper.AESZipFile(mem_fs.open('/hidden_dir/password_protected.zip', 'wb'),
'w',
compression=pyzipper.ZIP_LZMA,
encryption=pyzipper.WZ_AES) as zf:
zf.setpassword(secret_password)
zf.writestr('data.txt', data)
# Read encrypted password protected ZIP file from memory
with pyzipper.AESZipFile(mem_fs.open('/hidden_dir/password_protected.zip', 'rb')) as zf:
zf.setpassword(secret_password)
my_secrets = zf.read('data.txt')
print(my_secrets)
# output
b'abababababababababab'
UPDATED 03.21.2022
Reading through our comments you continue to raise concerns about the cryptography components of modules, such as pyzipper, but not 7Z LIB/SDK. Here is an academic paper on 7Z LIB/SDK version 19 cryptography.
Based on your concerns have you considered encrypting your data in memory prior to writing it to a zipfile?
Here is an example for doing this and writing the encrypted data to a file in memory:
import os
import fs
import base64
from cryptography.fernet import Fernet
from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives.kdf.pbkdf2 import PBKDF2HMAC
mem_fs = fs.open_fs('mem://')
mem_fs.makedir('hidden_dir')
password = b"password"
salt = os.urandom(16)
kdf = PBKDF2HMAC(
algorithm=hashes.SHA256(),
length=32,
salt=salt,
iterations=390000,
)
key = base64.urlsafe_b64encode(kdf.derive(password))
f = Fernet(key)
data = b'ab' * 10
encrypted_message = f.encrypt(data)
with mem_fs.open('hidden_dir/encrypted.text', 'wb') as in_file_in_memory:
in_file_in_memory.write(encrypted_message)
in_file_in_memory.close()
with mem_fs.open('hidden_dir/encrypted.text', 'rb') as out_file_in_memory:
raw_data = out_file_in_memory.read()
decrypted_data = f.decrypt(raw_data)
print(decrypted_data)
# output
b'abababababababababab'
Previously in the comments I mentioned key management, which is similar to maintaining a list of passwords for your zip archives.
I don't know your setup, but you could pregenerate keys in advance and stored them in a secure way for use in your code.
I don't have 7z installed on my Mac, so I could only give you pseudocode. The examples below aren't using 7z.
import os
import fs
import base64
import pyzipper
from zipfile import ZipFile
from cryptography.fernet import Fernet
mem_fs = fs.open_fs('mem://')
mem_fs.makedir('hidden_dir')
# pregenerate key
f = Fernet(b'-6_WO-GLrlXexdSbon_fKJoVOVBh66LdYrEM0Kvcwf0=')
data = b'ab' * 10
encrypted_message = f.encrypt(data)
with mem_fs.open('hidden_dir/encrypted.text', 'wb') as in_file_in_memory:
in_file_in_memory.write(encrypted_message)
in_file_in_memory.close()
# This uses standard ZIP with no password, but the data
# is encrypted
with mem_fs.open('hidden_dir/encrypted.text', 'rb') as out_file_in_memory:
raw_data = out_file_in_memory.read()
with ZipFile('archive.zip', mode='w') as zip_file:
zip_file.writestr('file.txt', raw_data)
# This uses pyzipper to create a password word protected
# encrypted file, which stores the encrypted.text.
# overkill, because the data is already encrypted prior
with mem_fs.open('hidden_dir/encrypted.text', 'rb') as out_file_in_memory:
raw_data = out_file_in_memory.read()
secret_password = b'super secret password'
# Create encrypted password protected ZIP file in-memory
with pyzipper.AESZipFile('password_protected.zip',
'w',
compression=pyzipper.ZIP_LZMA,
encryption=pyzipper.WZ_AES) as zf:
zf.setpassword(secret_password)
zf.writestr('data.txt', raw_data)
I'm still looking into how to pipe this encrypted.text to subprocess 7-zip.