← Back to HQ

The Mobile Bunker: Encryption on GrapheneOS (Termux Edition)

by Alien Investor

Sovereignty doesn't end at the edge of your desk. Take your digital fortress with you.

In part one we built the "Digital Bunker" on the Linux desktop. We learned that real security is based on auditability, not flashy apps. But investors and strategists are mobile. What good is the most secure archive at home if you need to access sensitive documents on the go or securely exfiltrate data?

Most mobile solutions are black boxes. You press a button, something happens, and you hope the developer doesn't have a master key. That's unacceptable.

We use GrapheneOS, the only mobile operating system that takes security architecture seriously. And we use Termux, a terminal emulator that turns your smartphone into a full Linux computer.

The goal: one workflow. Two devices. Identical math.
An archive you encrypt on your Tuxedo laptop must be openable on your GrapheneOS phone — and vice versa.

1. Preparation: Getting Termux Ready

On GrapheneOS, the best way to install Termux is via F-Droid (not the Play Store — that version is outdated).
Once you have the black terminal in front of you, update the packages and install the necessary tools. This is the foundation.

Type the following commands one after another:

pkg update && pkg upgrade
pkg install termux-tools tar gnupg

Storage Access

Termux lives in isolation. For the scripts to access your Downloads (where your data lives), we need to bridge to the Android filesystem.

Run:

termux-setup-storage

Confirm the dialog on screen ("Allow").

Now create a folder for your tools:

mkdir -p ~/Skripte

2. Part 1: The Mobile Shield (Encryption)

The encrypt-folder.sh script for Termux is intelligent. It automatically detects whether it's running on an Android system and routes the output to the Downloads folder, so you can easily find and share the encrypted file later.

Under the Hood: The Security Mechanics

Before we copy the code, pay attention to a detail that separates professional code from hobbyist scripts. At the start of the script you'll find the "Helpers" section:

This is what code that won't let you down in an emergency looks like.

Create the file:

nano ~/Skripte/encrypt-folder.sh

Paste this code:

#!/usr/bin/env bash
# encrypt-folder.sh — Pack folder losslessly and encrypt symmetrically (AES-256),
# without a plaintext intermediate file. Also generates a .sha256.
# Phone (GrapheneOS/Termux): output to ~/storage/downloads
# PC (TUXEDO OS): output to $HOME
#
# S2K hardening: SHA512 + AES256 + maximum iterations (65011712)
# → Brute-force attacks on the password become 100x more expensive.

set -Eeuo pipefail
umask 077

# -------------------- Helpers --------------------
die() { printf "❌ %s\n" "$*" >&2; exit 1; }
need() { command -v "$1" >/dev/null 2>&1 || die "Required program missing: $1"; }

need tar
need gpg
need sha256sum

# Determine output destination based on system
OUT_DIR="$HOME"
if [ -d "$HOME/storage/downloads" ]; then
  OUT_DIR="$HOME/storage/downloads"
fi

# Input: optional as argument, otherwise prompt
INPUT="${1-}"
if [ -z "$INPUT" ]; then
  printf "📁 Please enter the folder name: "
  IFS= read -r INPUT
fi

[ -n "$INPUT" ] || die "No name entered."

# Normalize path:
# Allowed: SAP | storage/downloads/SAP | ~/storage/downloads/SAP
#          /sdcard/Download/SAP | /storage/emulated/0/Download/SAP | /full/path/SAP
case "$INPUT" in
  ~/*) SRC="$HOME/${INPUT#~/}" ;;
  storage/*) SRC="$HOME/$INPUT" ;;  # Termux symlink
  /sdcard/Download/*)
      SRC="$HOME/storage/downloads/${INPUT#/sdcard/Download/}" ;;
  /storage/emulated/0/Download/*)
      SRC="$HOME/storage/downloads/${INPUT#/storage/emulated/0/Download/}" ;;
  /*) SRC="$INPUT" ;;
  *)
      if [ -d "$HOME/storage/downloads/$INPUT" ]; then
        SRC="$HOME/storage/downloads/$INPUT"
      else
        SRC="$HOME/$INPUT"
      fi
      ;;
esac

[ -e "$SRC" ] || die "Path not found: $SRC"
[ -d "$SRC" ] || die "This is not a directory: $SRC"

BASE="$(basename "$SRC")"

# Optional: replace spaces in name with underscore (for the output file only)
BASE_SAFE="${BASE// /_}"

OUT_FILE="$OUT_DIR/Encrypted_${BASE_SAFE}.tar.gz.gpg"

# Avoid collisions
if [ -e "$OUT_FILE" ]; then
  OUT_FILE="$OUT_DIR/Encrypted_${BASE_SAFE}_$(date +%Y-%m-%d_%H-%M-%S).tar.gz.gpg"
fi

printf "📦 Packing & encrypting → %s\n" "$OUT_FILE"

# Archive + encrypt without plaintext intermediate file
# S2K hardening: stronger key derivation against brute force
tar -C "$(dirname "$SRC")" -cz "$BASE" \
| gpg --symmetric \
    --cipher-algo AES256 \
    --s2k-cipher-algo AES256 \
    --s2k-digest-algo SHA512 \
    --s2k-count 65011712 \
    -o "$OUT_FILE" \
|| die "gpg failed"

# Write checksum
sha256sum "$OUT_FILE" > "${OUT_FILE}.sha256"

printf "✅ Done:\n   %s\n   %s\n   Location: %s\n" \
  "$(basename "$OUT_FILE")" "$(basename "${OUT_FILE}.sha256")" "$OUT_DIR"

(Save in nano with CTRL+O, Enter, then CTRL+X)

3. Part 2: The Mobile Key (Decryption)

On the go you often run into a problem: cloud services or downloads rename files. File.gpg suddenly becomes File.gpg.pgp or File (1).gpg.
This script is the "Cloud Edition." It's extremely robust, finds your file even with wrong extensions, and verifies the SHA256 checksum.

Create the file:

nano ~/Skripte/decrypt-folder.sh

Paste this code:

#!/usr/bin/env bash
# decrypt-folder.sh (Cloud Edition)
# - Finds .gpg AND .pgp (double extension from cloud/download)
# - Smart SHA check (also handles the extra .pgp extension)

set -Eeuo pipefail
umask 077

export GPG_TTY="${GPG_TTY:-$(tty 2>/dev/null || true)}"

DL_DIR="$HOME/storage/downloads"

die(){ printf "❌ %s\n" "$*" >&2; exit 1; }

# --- 1. Automatic file selection (GPG & PGP) ---
NAME="${1-}"
INPUT=""

if [ -z "$NAME" ]; then
  # Search for .gpg OR .pgp, sorted by time (newest first)
  # 2>/dev/null suppresses errors if one type is absent
  LATEST="$(ls -t "$DL_DIR"/*.gpg "$DL_DIR"/*.pgp 2>/dev/null | head -n1 || true)"

  if [ -n "$LATEST" ]; then
    INPUT="$LATEST"
    printf "🤖 File found: %s\n" "$(basename "$INPUT")"
  else
    printf "No file found. Enter name: "
    IFS= read -r NAME
    [ -n "$NAME" ] || die "Aborted."
  fi
fi

# Fallback: manual path search
if [ -z "$INPUT" ]; then
    # Try various variants
    VARIANTS=(
      "${NAME}"
      "${NAME}.gpg"
      "${NAME}.pgp"
      "${NAME}.gpg.pgp"
      "Encrypted_${NAME}.gpg"
    )

    for v in "${VARIANTS[@]}"; do
        # Check in PWD and Downloads
        if [ -f "$PWD/$v" ]; then INPUT="$PWD/$v"; break; fi
        if [ -f "$DL_DIR/$v" ]; then INPUT="$DL_DIR/$v"; break; fi
    done
fi

[ -n "$INPUT" ] || die "Source file not found."

# --- 2. Smart SHA256 check ---
# Case A: standard (File.gpg.sha256)
SHA_CANDIDATE_1="${INPUT}.sha256"

# Case B: cloud error (File.gpg.pgp -> File.gpg.sha256)
SHA_CANDIDATE_2="${INPUT%.pgp}.sha256"

SHA_FILE=""

if [ -f "$SHA_CANDIDATE_1" ]; then
    SHA_FILE="$SHA_CANDIDATE_1"
elif [ -f "$SHA_CANDIDATE_2" ]; then
    SHA_FILE="$SHA_CANDIDATE_2"
    echo "ℹ️  Correcting SHA path (ignoring .pgp extension)..."
fi

if [ -n "$SHA_FILE" ]; then
    printf "🔎 Checking integrity (SHA256)..."
    EXPECTED=$(awk '{print $1}' "$SHA_FILE")
    ACTUAL=$(sha256sum "$INPUT" | awk '{print $1}')

    if [ "$EXPECTED" = "$ACTUAL" ]; then
        echo " ✅ OK."
    else
        echo " ❌ ERROR!"
        echo "   WARNING: Checksums do not match!"
        echo "   File may be corrupted."
        printf "   Continue anyway? (y/N) "
        read -r -n 1 REPLY
        echo
        if [[ ! $REPLY =~ ^[Yy]$ ]]; then
            die "Aborted."
        fi
    fi
else
    echo "ℹ️  No .sha256 file found (check skipped)."
fi

# --- 3. Decrypt & unpack ---
printf "🔓 Decrypting & unpacking..."

if gpg --quiet --decrypt "$INPUT" | tar -xz; then
    echo " ✅ Done."
    echo "📂 Folder is in: $PWD"
elif gpg --quiet --pinentry-mode loopback --decrypt "$INPUT" | tar -xz; then
    echo " ✅ Done."
    echo "📂 Folder is in: $PWD"
else
    die "Error."
fi

Make both scripts executable:

chmod +x ~/Skripte/encrypt-folder.sh ~/Skripte/decrypt-folder.sh

4. The Workflow in the Field

Here's the tactical procedure for moving your data securely.

Scenario A: Encrypt and Decrypt on the Phone (Loop)

  1. You have a folder (e.g. Finances) in your Downloads area.
  2. Open Termux.
  3. Start the script: ~/Skripte/encrypt-folder.sh
  4. Type the folder name: Finances
  5. Result: Your regular Downloads folder now contains Encrypted_Finances.tar.gz.gpg and the checksum.
  6. Want to test/decrypt it? Just run ~/Skripte/decrypt-folder.sh. The decrypted files will be in the Termux home directory (see step 3).

Scenario B: Decrypt Data from PC (The Real Case)

You've transferred an encrypted file (e.g. Encrypted_Backup.tar.gz.gpg) from your PC to your phone.

5. Why Auditability Is King

You could download an app from the AppStore called "AES Safe Box." But do you know what it does with your keys?

No magic. Just math. That's the Alien Investor way.

With these scripts you see every command:

Background: The Foundation

This is part 2 of the series. Find the introduction and the desktop scripts here:
Part 1: The Digital Bunker

Tools for Real Owners (Advertising/Affiliate)

Tools I use myself — for Bitcoin self-custody and digital sovereignty:

Note: Some links are affiliate links. If you use them, you support my work at no extra cost to you. Thanks!


Recharge (Donate)

Send fuel to the mothership

Thanks for your support — for free content, financial sovereignty, and the alien resistance!