Your data is encrypted with open, standard algorithms that any computer can decrypt — without needing this app. This guide walks you through it step by step, even if you have never used a command-line tool before.
Estimated time: 5 – 10 minutes.
WPUiBcZ2b20Riq7IMDBNjgRVkgnAiKDTjOdXCpch1YNOdMmGIV4X8tfQxD1rcdOM...We will use PowerShell 7.4 or newer, a free command-line tool from Microsoft. It has everything needed built in — no extra downloads beyond PowerShell itself.
The easiest way is through the Microsoft Store — it takes about two minutes:
-win-x64.msi and run it, clicking Next on each screen.
PS C:\Users\YourName>.Run this first. It remembers your current PSReadLine history setting, then stops new commands from being saved to its persistent history file for the rest of this PowerShell session.
$previousHistoryStyle = (Get-PSReadLineOption).HistorySaveStyle; Set-PSReadLineOption -HistorySaveStyle SaveNothing
TEXT TO DECRYPT.PASSWORD and replace it with the password used to encrypt the message.[byte[]]$bytes=[Convert]::FromBase64String(('TEXT TO DECRYPT' -replace '\s','')); [byte[]]$salt=$bytes[0..15]; [byte[]]$iv=$bytes[16..27]; [byte[]]$ciphertext=$bytes[28..($bytes.Length-17)]; [byte[]]$tag=$bytes[($bytes.Length-16)..($bytes.Length-1)]; $pbkdf2=[System.Security.Cryptography.Rfc2898DeriveBytes]::new([System.Text.Encoding]::UTF8.GetBytes('PASSWORD'),$salt,100000,[System.Security.Cryptography.HashAlgorithmName]::SHA256); [byte[]]$key=$pbkdf2.GetBytes(32); $pbkdf2.Dispose(); $aesGcm=[System.Security.Cryptography.AesGcm]::new($key,16); [byte[]]$plaintext=New-Object byte[] $ciphertext.Length; $aesGcm.Decrypt($iv,$ciphertext,$tag,$plaintext); $aesGcm.Dispose(); Write-Host ([System.Text.Encoding]::UTF8.GetString($plaintext))
TEXT TO DECRYPT and PASSWORD.it's ready becomes 'it''s ready'. Spaces, dollar signs, and other punctuation need no other change inside PowerShell single quotes.Run the following after you have finished reading or copying the message. It clears the variables, clears PowerShell's session history and PSReadLine's in-memory recall list, clears the clipboard, restores your earlier history setting, and clears the visible screen.
$bytes=$null; $salt=$null; $iv=$null; $ciphertext=$null; $tag=$null; $key=$null; $plaintext=$null; Clear-History; [Microsoft.PowerShell.PSConsoleReadLine]::ClearHistory(); Set-Clipboard -Value ''; Set-PSReadLineOption -HistorySaveStyle $previousHistoryStyle; $previousHistoryStyle=$null; Clear-Host
Clear-Host does not guarantee that every terminal application has discarded its scrollback. In Windows Terminal, open the command palette with Ctrl+Shift+P, run Clear Buffer, then close the tab when finished.Clear-History clears every command from the current PowerShell session history, not only the decryption command. It does not delete the persistent PSReadLine history file. The separate PSReadLine in-memory recall list is cleared before history saving is restored, so unrelated history saved before this session is preserved.Remove-Item (Get-PSReadLineOption).HistorySavePath -Force deletes ALL saved PowerShell command history, not only this decryption session.Copy the command below into PowerShell. Then replace everything between the two quote marks with your actual encrypted text — delete the placeholder text entirely and paste yours in its place.
"PASTE_YOUR_FULL_ENCRYPTED_TEXT_HERE" | Set-Content "$HOME\secret.txt" -Encoding utf8
Press Enter. This saves your encrypted text as a file called secret.txt in your home folder (C:\Users\YourName\).
Copy the entire script below. Before you paste it into PowerShell:
'YOUR_PASSWORD_HERE'Then paste the whole thing into PowerShell (right-click to paste) and press Enter.
$password = 'YOUR_PASSWORD_HERE'
$bytes = [Convert]::FromBase64String((Get-Content "$HOME\secret.txt" -Raw).Trim())
[byte[]]$salt = $bytes[0..15]
[byte[]]$iv = $bytes[16..27]
[byte[]]$ciphertext = $bytes[28..($bytes.Length - 17)]
[byte[]]$tag = $bytes[($bytes.Length - 16)..($bytes.Length - 1)]
$pbkdf2 = [System.Security.Cryptography.Rfc2898DeriveBytes]::new(
[System.Text.Encoding]::UTF8.GetBytes($password),
$salt, 100000,
[System.Security.Cryptography.HashAlgorithmName]::SHA256)
[byte[]]$key = $pbkdf2.GetBytes(32)
$pbkdf2.Dispose()
$aesGcm = [System.Security.Cryptography.AesGcm]::new([byte[]]$key)
$plaintext = New-Object byte[] $ciphertext.Length
$aesGcm.Decrypt($iv, $ciphertext, $tag, $plaintext)
$aesGcm.Dispose()
Write-Host ([System.Text.Encoding]::UTF8.GetString($plaintext))
'? Write it as two single quotes: '' inside the script. Example: if your password is it's, write 'it''s'.$? Single quotes protect it — no changes needed.
After a second or two your decrypted message will appear in the terminal window. You can select and copy it just like normal text.
$password line and run the script again.We will use Python 3 and a free helper package called cryptography. The setup takes about 5 minutes and only needs to be done once.
Terminal is the command-line tool on Mac. You can find it two ways:
A window opens with a prompt — this is your terminal. You type commands here and press Enter to run them.
Type the following and press Enter:
python3 --version
Python 3.x.x — Python is installed. Go to Step 3.Type this and press Enter:
pip3 install cryptography
Wait until you see a line that says Successfully installed cryptography-.... This only needs to be done once ever.
python3 -m pip install cryptography
Modern macOS uses zsh by default. Run this first so the sensitive pasted command goes into a temporary history list instead of your normal saved history:
fc -p
echo $SHELL does not end in /zsh, do not use this command. See the Linux section's Bash instructions if your shell is Bash.TEXT TO DECRYPT.PASSWORD and replace it with the password used to encrypt the message.python3 - <<'PY'
import base64
from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives.kdf.pbkdf2 import PBKDF2HMAC
from cryptography.hazmat.primitives.ciphers.aead import AESGCM
encrypted_bytes = base64.b64decode("".join("TEXT TO DECRYPT".split()), validate=True)
salt = encrypted_bytes[:16]
iv = encrypted_bytes[16:28]
ciphertext_and_tag = encrypted_bytes[28:]
kdf = PBKDF2HMAC(algorithm=hashes.SHA256(), length=32, salt=salt, iterations=100000)
key = kdf.derive("PASSWORD".encode("utf-8"))
plaintext_bytes = AESGCM(key).decrypt(iv, ciphertext_and_tag, None)
print(plaintext_bytes.decode("utf-8"))
PY
TEXT TO DECRYPT and PASSWORD.\" for a double quote and \\ for a backslash. Spaces, single quotes, Swedish characters, and emoji need no change.The Python process has ended, so its password, encrypted input, key, and plaintext variables are no longer available in the shell. Run these commands individually:
pbcopy < /dev/null
fc -P
clear
pbcopy empties the macOS clipboard. fc -P discards the temporary zsh history context and restores your normal history. clear clears the visible screen.
clear does not necessarily remove earlier output from scrollback. In Apple's Terminal app, press ⌘ Cmd+K to clear scrollback, then close the tab. Other terminal apps may use a menu item named Clear Scrollback or Clear Buffer. This does not guarantee secure memory erasure.Type this command and press Enter:
cat > ~/secret.txt
The cursor will move to a new blank line — that means Terminal is waiting for you to type or paste something.
pbpaste > ~/secret.txtWe will use nano, a simple text editor built into Mac. Type this and press Enter:
nano ~/decrypt.py
The terminal changes to show a plain text editor. Now paste the script below (⌘ Cmd+V). Before pasting, change YOUR_PASSWORD_HERE to your actual password (keep the double quote marks around it).
import base64, os
from cryptography.hazmat.primitives.kdf.pbkdf2 import PBKDF2HMAC
from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives.ciphers.aead import AESGCM
password = "YOUR_PASSWORD_HERE".encode("utf-8")
with open(os.path.expanduser("~/secret.txt")) as f:
data = base64.b64decode(f.read().strip())
salt, iv, ciphertext = data[:16], data[16:28], data[28:]
kdf = PBKDF2HMAC(algorithm=hashes.SHA256(), length=32, salt=salt, iterations=100000)
key = kdf.derive(password)
plaintext = AESGCM(key).decrypt(iv, ciphertext, None)
print(plaintext.decode("utf-8"))
To save and close nano:
decrypt.py"? Write it as \" inside the script. Write a backslash as \\. Spaces, Swedish characters, and emoji work as written.
Type this and press Enter:
python3 ~/decrypt.py
Your decrypted message will appear on the next line.
nano ~/decrypt.py), check the password carefully — watch out for capital letters and extra spaces — save, and run again.pip3 install cryptographyWe will use Python 3 and the free cryptography package. Python 3 is pre-installed on most Linux distributions.
How to open a terminal depends on your desktop:
konsole.Type this and press Enter:
python3 --version
If you see Python 3.x.x — skip to Step 3. If not, install it:
sudo apt update && sudo apt install python3 python3-pip
sudo dnf install python3 python3-pip
sudo pacman -S python python-pip
You will be asked for your system password — type it and press Enter. Note: the password will not appear as you type. That is normal.
pip3 install cryptography
Wait until you see Successfully installed cryptography-.... This only needs to be done once.
pip3 install --user cryptography
First check your shell:
basename "$SHELL"
If it says bash, run:
OLD_HISTCONTROL=$HISTCONTROL; HISTCONTROL=ignorespace
The decryption code below deliberately begins with one space. Bash's ignorespace setting keeps that pasted command out of its history. Your earlier setting is restored during cleanup.
If it says zsh, run:
fc -p
This pushes an empty temporary zsh history context, which is discarded during cleanup.
TEXT TO DECRYPT.PASSWORD and replace it with the password used to encrypt the message. python3 - <<'PY'
import base64
from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives.kdf.pbkdf2 import PBKDF2HMAC
from cryptography.hazmat.primitives.ciphers.aead import AESGCM
encrypted_bytes = base64.b64decode("".join("TEXT TO DECRYPT".split()), validate=True)
salt = encrypted_bytes[:16]
iv = encrypted_bytes[16:28]
ciphertext_and_tag = encrypted_bytes[28:]
kdf = PBKDF2HMAC(algorithm=hashes.SHA256(), length=32, salt=salt, iterations=100000)
key = kdf.derive("PASSWORD".encode("utf-8"))
plaintext_bytes = AESGCM(key).decrypt(iv, ciphertext_and_tag, None)
print(plaintext_bytes.decode("utf-8"))
PY
TEXT TO DECRYPT and PASSWORD are no longer visible. If either placeholder remains, do not run the code. If you use Bash, keep the space before python3.\" for a double quote and \\ for a backslash. Spaces, single quotes, Swedish characters, and emoji need no change.The Python subprocess has ended, so its password, encrypted input, key, and plaintext variables are no longer available in the shell.
If you use Bash, run:
HISTCONTROL=$OLD_HISTCONTROL; unset OLD_HISTCONTROL; clear
If you use zsh, run:
fc -P; clear
To clear the clipboard, use the command matching your desktop:
wl-copy --clear (requires the optional wl-clipboard package).printf '' | xclip -selection clipboard (requires the optional xclip package).clear only clears the visible screen in many terminal applications. Use your terminal's Clear Scrollback or Clear Buffer action, then close the tab. These cleanup steps reduce exposure but do not guarantee secure memory erasure.Type this command and press Enter:
cat > ~/secret.txt
The cursor moves to a blank line — Terminal is waiting for input.
Open the nano text editor:
nano ~/decrypt.py
Paste the script below. Change YOUR_PASSWORD_HERE to your actual password first (keep the double quote marks).
To paste in nano: Ctrl+Shift+V (or right-click if your terminal supports it).
import base64, os
from cryptography.hazmat.primitives.kdf.pbkdf2 import PBKDF2HMAC
from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives.ciphers.aead import AESGCM
password = "YOUR_PASSWORD_HERE".encode("utf-8")
with open(os.path.expanduser("~/secret.txt")) as f:
data = base64.b64decode(f.read().strip())
salt, iv, ciphertext = data[:16], data[16:28], data[28:]
kdf = PBKDF2HMAC(algorithm=hashes.SHA256(), length=32, salt=salt, iterations=100000)
key = kdf.derive(password)
plaintext = AESGCM(key).decrypt(iv, ciphertext, None)
print(plaintext.decode("utf-8"))
Save and exit nano:
sudo apt install nano (Ubuntu/Debian) or sudo dnf install nano (Fedora).
"? Write it as \". Write a backslash as \\. Spaces, Swedish characters, and emoji work as written.
python3 ~/decrypt.py
Your decrypted message will appear on the next line.
nano ~/decrypt.py, fix the password, save, and run again.pip3 install cryptography or pip3 install --user cryptographyThis tool encrypts using only open, standardised algorithms — any implementation that follows the same format will produce the same result:
| Bytes | Length | Contents |
|---|---|---|
| 0 – 15 | 16 bytes | Random salt (for PBKDF2 key derivation) |
| 16 – 27 | 12 bytes | Random IV / nonce (for AES-GCM) |
| 28 – (end−17) | variable | Ciphertext |
| last 16 | 16 bytes | GCM authentication tag |
PBKDF2-SHA256 (100,000 iterations) — open standard, defined in RFC 8018.
AES-256-GCM — NIST standard, available in .NET, Python, OpenSSL, Go, Rust, and more.