How to Decrypt a GPG File with a Passphrase in Python
Decrypt a GPG-encrypted file using a passphrase via the gpg CLI wrapped in a reusable Python function.
Python code
33 linesimport subprocess
import tempfile
from pathlib import Path
def decrypt_gpg_file(input_file: str, passphrase: str) -> str:
"""Decrypt a GPG file using a passphrase and return the plaintext."""
result = subprocess.run(
["gpg", "--batch", "--yes", "--passphrase", passphrase, "--decrypt", input_file],
capture_output=True,
text=True,
check=False,
)
if result.returncode != 0:
raise RuntimeError(f"GPG decryption failed: {result.stderr.strip()}")
return result.stdout
if __name__ == "__main__":
# Create a mock encrypted file for demonstration
with tempfile.TemporaryDirectory() as tmpdir:
plaintext_path = Path(tmpdir) / "secret.txt"
encrypted_path = Path(tmpdir) / "secret.txt.gpg"
plaintext_path.write_text("Hello, GPG world!", encoding="utf-8")
subprocess.run(
["gpg", "--batch", "--yes", "--passphrase", "demo-pass", "-c", "-o", str(encrypted_path), str(plaintext_path)],
check=True,
capture_output=True,
)
decrypted = decrypt_gpg_file(str(encrypted_path), "demo-pass")
print(decrypted)
Output
Hello, GPG world!
How it works
This function invokes the gpg command-line tool with --batch and --yes to run non-interactively. The passphrase is passed directly as a command argument, which works for trusted environments but is less secure than using a keyring or --pinentry-mode loopback. subprocess.run captures stdout and stderr, so plaintext is returned as a string and errors surface as a RuntimeError. The demo creates a temporary file, encrypts it with symmetric encryption (-c), then decrypts it to verify the function end-to-end.
Common mistakes
- Assuming gpg is installed — the subprocess call fails with FileNotFoundError on systems without GPG.
- Passing a passphrase on the command line exposes it in process listings on multi-user systems.
- Forgetting to use `--batch` which causes gpg to hang waiting for terminal input.
- Using `check=True` without capturing stderr, so the error message is lost on failure.
Variations
- Use `--pinentry-mode loopback` with `--passphrase-fd 0` to read the passphrase from stdin instead of argv.
- Wrap the call with `timeout=30` in `subprocess.run` to avoid hangs on corrupted files.
Real-world use cases
- Automating decryption of encrypted configuration files during CI/CD deployment steps.
- Batch-decrypting legacy customer reports stored as GPG files in an archive migration job.
- Building a lightweight secret-retrieval script that unlocks encrypted credentials for background workers.
Sponsored
More from Automation & scripting
- Aggregate Log Errors Count by Hour in Python easy
- Automate Tweeting New Blog Posts in Python easy
- Automatically Clean Temporary Files from Applications Using Python medium
- Automatically Download the Latest Software Release from GitHub with Python medium
- Automatically Generate Charts from CSV Files with One Command medium
- Automatically Generate Hardware Inventory Reports in Python easy
Keep learning
Related tutorials and quizzes for this topic.