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.

Easy Python 3.9+ Aug 9, 2026 Automation & scripting 13 views 0 copies

Python code

33 lines
Python 3.9+
import 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

stdout
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

  1. Use `--pinentry-mode loopback` with `--passphrase-fd 0` to read the passphrase from stdin instead of argv.
  2. 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

Run this sample

Open the browser IDE to tweak the example and see results without installing anything.

Open editor

More from Automation & scripting

Related tutorials and quizzes for this topic.