SecureTar
SecureTar is a Python library designed for handling encrypted tarfile backups. It acts as a streaming wrapper around Python's standard `tarfile` module, providing robust encryption capabilities. The library is actively maintained with frequent updates, often introducing significant breaking changes related to its file format and API, notably driven by advancements in cryptographic standards and its use in projects like Home Assistant.
Common errors
-
ReadError: not a gzip file
cause Attempting to decrypt an encrypted `securetar` archive with an incorrect password, an outdated decryption script, or a version of `securetar` that doesn't support the specific file format (e.g., v3 introduced in 2026.2.0).fixVerify the password is correct. Ensure the `securetar` library version used for decryption is compatible with the version used for encryption. If using custom scripts, update them to reflect the latest `securetar` API and file format changes. -
Cannot open, not an archive (when using 7-Zip or standard tools)
cause SecureTar creates a custom encrypted format that is not directly compatible with standard `.tar.gz` or `.zip` tools like 7-Zip for decryption or extraction.fixAlways use the `securetar` Python library itself for decrypting and extracting contents from a `securetar` archive. Standard archive tools will not recognize the encrypted stream as a valid archive before decryption. -
Key derivation failed or 'invalid password' for existing backups after library upgrade.
cause The key derivation function was moved into the library in version 2025.12.0, causing API changes for how passwords are processed into encryption keys. This can lead to incompatibility with older methods of deriving keys or with backups created using older library versions that processed passwords differently.fixReview the API changes in `securetar` versions 2025.12.0 and later. Ensure your application uses the `SecureTarFile` class directly with the password parameter, allowing the library to handle key derivation internally according to the current format specification.
Warnings
- breaking Version 2026.2.0 introduced a new file format (version 3) using Argon2 for key derivation, Blake2 for subkey derivation, and ChaCha13Poly1305 for encryption. This was a major rewrite breaking most existing implementations.
- breaking Version 2025.12.0 moved the key derivation function into the library itself, requiring a breaking change in the API. Any custom password-to-key derivation logic outside the library will no longer be compatible.
- breaking Version 2025.1.3 added a new file header for encrypted tar files, making the file format *not* backwards compatible for writing new archives, although the library retains the ability to read older formats.
- breaking The minimum required Python version was bumped to 3.11 in release 2025.12.0.
- gotcha Some earlier versions had potential issues with non-random IVs or padding, which could lead to backup corruption or make decryption less secure. These issues were addressed in later versions, particularly with the introduction of v3.
Install
-
pip install securetar
Imports
- SecureTarFile
from securetar import SecureTarFile
- atomic_contents_add
from securetar import atomic_contents_add
Quickstart
import os
from pathlib import Path
from securetar import SecureTarFile, atomic_contents_add
# Create a dummy file for backup
dummy_file_path = Path("my_data.txt")
dummy_file_path.write_text("This is some sensitive data.")
# Define backup path and a password
backup_file_path = Path("my_secure_backup.tar")
backup_password = os.environ.get('SECURETAR_PASSWORD', 'a_very_secret_password_123')
print(f"Creating secure backup to {backup_file_path}...")
# Create a secure tar archive
with SecureTarFile(backup_file_path, 'w', password=backup_password) as tar_file:
atomic_contents_add(tar_file, dummy_file_path, arcname=dummy_file_path.name)
print(f"Backup created: {backup_file_path}")
# Verify by attempting to read it
print(f"Attempting to read from {backup_file_path}...")
try:
with SecureTarFile(backup_file_path, 'r', password=backup_password) as tar_file:
members = tar_file.getnames()
print(f"Contents of backup: {members}")
# Example of extracting a file
extracted_path = Path("extracted_data.txt")
tar_file.extract(dummy_file_path.name, path=".")
print(f"Extracted '{dummy_file_path.name}' to '{extracted_path}'")
extracted_path.unlink() # Clean up
except Exception as e:
print(f"Error reading backup: {e}")
finally:
dummy_file_path.unlink() # Clean up original dummy file
backup_file_path.unlink() # Clean up backup file