Encrypt a file with a password
Choose a file and a strong password to lock it with AES-256 encryption, then download the encrypted copy. To open it again, drop it back here with the same password. Everything happens on your device, so the file is never uploaded.
Name the encrypted copy "encrypted.stoutnook" instead. The real name is stored inside and comes back when it's decrypted.
How it works
- Encryption
- AES-256-GCM
- Key from your password
- Argon2id, 64 MB, 3 passes
- Where it happens
- On this device
- You get
- A .stoutnook file
Nothing is uploaded: the page does all the work, and it keeps working if you go offline after it loads.
- Nothing is uploaded
- Free, no sign-up
- Works on phone and desktop
How to encrypt a file with a password
- 1
Drop the file you want to protect on the box above, or click to choose it. Any type of file works, and nothing is uploaded.
- 2
Type a strong password twice, or click Suggest a passphrase and save the words somewhere safe.
- 3
Click Encrypt file, then Download encrypted file. You get a copy whose name ends in .stoutnook.
- 4
To open it later, drop the encrypted file here (the tool switches to Decrypt), enter the password and download the original.
Features
AES-256-GCM encryption
Standard, widely trusted encryption that also detects any change to the file, so tampering never goes unnoticed.
Argon2id password protection
Your password is turned into a key with 64 MB of memory per try, which makes guessing it slow and costly.
Never uploaded
The encryption runs in your browser, on your device. Your file and password are never sent or stored.
An open, documented format
The file format is published below with a Python script, so you can always decrypt without this site.
What happens when you encrypt a file
When you click Encrypt file, your browser does all the work on your own device. First it turns your password into a 256-bit key. Then it reads the file one megabyte at a time, encrypts each piece and seals it with a tag that proves it hasn't been changed. The result is a new file ending in .stoutnook that looks like random noise to anyone without the password. Your original file isn't touched, and nothing is uploaded: you can load this page, switch off your internet connection and it still works.
AES-256-GCM, in plain words
AES is the encryption standard chosen by the US National Institute of Standards and Technology (NIST) and used everywhere from HTTPS to disk encryption and messaging apps. "256" is the key length: far more possible keys than anyone could ever try. GCM, specified in NIST SP 800-38D, adds an authentication tag to every piece. If a single bit of the encrypted file is changed, by damage or on purpose, decryption stops with an error instead of handing you a corrupted file. Each piece also records its position and whether it's the last one, so a file that has been cut short, padded or shuffled is caught too.
Argon2id: why the first step takes a moment
A password isn't a key, and a fast conversion would let an attacker test billions of guesses. Argon2id, the recommended form of Argon2 (winner of the 2015 Password Hashing Competition, standardized in RFC 9106), makes every guess deliberately expensive: it has to fill 64 MB of memory and pass over it 3 times. Those are the memory and pass count of the RFC's second recommended setting, and well above the minimum in the OWASP Password Storage Cheat Sheet (19 MiB and 2 passes). A random 16-byte salt makes every file's key different, even with the same password. On a computer this takes a fraction of a second; phones take a little longer.
Your password is the whole lock
Anyone who gets a copy of the encrypted file can try passwords on their own computers, as fast as their hardware allows, for as long as they like, with no lockout. Argon2id slows each guess down, but it can't save a password that's short or predictable. Names, dates, words with a number on the end and anything you've used before are among the first things attackers try, whatever symbols you add.
| Random password | Example | Strength | Average time to guess* |
|---|---|---|---|
| 8 random characters | k#9Lp2!x | 52 bits | 52 years |
| 4 random words | cubicle-avenue-sprout-oxidize | 52 bits | 58 years |
| 12 random characters | Vb7$qM2!rT9z | 77 bits | 3 billion years |
| 6 random words | cubicle-avenue-sprout-oxidize-mammal-reward | 78 bits | 4 billion years |
| 16 random characters | h7#Kq2$Lw9!pX4@n | 103 bits | trillions of years |
*For an attacker making a million guesses a second. With these Argon2id settings, one desktop processor core manages about 10 guesses a second (we measured it), so that's a large, well-funded attack. Don't use the examples: anything published ends up on attackers' lists. Computers keep getting faster, so leave a wide margin: for anything that matters, use at least 6 random words or 16 random characters. The passphrase generator makes word passphrases that are easy to type and to read out over the phone, and the password strength checker spots the patterns attackers try first.
Sharing an encrypted file safely
- Send the file and the password separately. If both are in the same email, anyone who reads that email has everything.
- Use a different kind of channel for the password: a phone call, a text message, a different messaging app, or in person.
- Don't put hints in the email, such as "the password is your dog's name".
- The person opening it needs nothing special: they drop the file on this page, choose Decrypt and type the password.
What encryption doesn't protect
- The fact that a file exists, and its rough size. Anyone who sees the encrypted file can tell how big it is and when it was sent, and the email or upload around it isn't encrypted.
- A compromised device. Malware or a keylogger on your computer or the recipient's can capture the password, or the file before encryption and after decryption.
- The recipient. Once someone decrypts the file, they can copy or forward it like any other file.
- A forgotten password. There is no recovery. Keep the password safe before you delete the original.
For the files on your own computer and phone, turn on full-disk encryption (BitLocker on Windows, FileVault on a Mac, and a screen lock on phones). Use this tool for individual files you send, back up to the cloud or store on a USB stick. For text such as account details or a Wi-Fi password, encrypt text gives you a block you can paste into an email or chat.
How big a file can I encrypt?
Files are processed in 1 MB pieces, so they never have to fit in memory twice. We tested the encryption engine with files over 1 GB, and it's designed for files up to about 2 GB on a desktop or laptop. Your browser holds the encrypted copy until you save it, so phones and tablets, which have less memory, may manage less. To check that a file you downloaded or decrypted is intact, the file checksum calculator gives you its SHA-256 fingerprint.
Decrypt without this site
Your files shouldn't depend on a website staying online, so the format is published here in full. Every number is big-endian.
The StoutNook format, version 1
A file starts with a 48-byte header:
| Offset | Bytes | Field (value used by this page) |
|---|---|---|
| 0 | 7 | Magic: the ASCII letters STOUTNK |
| 7 | 1 | Format version: 1 |
| 8 | 1 | Key method: 1 = Argon2id (version 1.3) |
| 9 | 1 | Argon2 parallelism (lanes): 1 |
| 10 | 4 | Argon2 memory in KiB: 65,536 |
| 14 | 4 | Argon2 passes: 3 |
| 18 | 16 | Salt (random) |
| 34 | 8 | Nonce prefix (random) |
| 42 | 4 | Bytes of the original per chunk: 1,048,576 |
| 46 | 2 | Metadata size before sealing: 256 for most files (more for very long names), 0 for messages |
- Key: Argon2id over the password (Unicode-normalized to NFC, then UTF-8) with the salt and the header's settings, giving 32 bytes: an AES-256-GCM key.
- Nonce for record n: the 8-byte nonce prefix followed by n as a 4-byte number.
- Additional authenticated data: the 48 header bytes followed by one flag byte: 0 for a chunk, 1 for the last chunk, 2 for the metadata record.
- Metadata record (files only): record 0, sealed with flag 2, so it takes the metadata size plus 16 bytes. It holds a 2-byte length, then that many bytes of JSON such as
{"name":"report.pdf"}, then zero padding to a multiple of 256 bytes so the name's length isn't revealed. - Chunks: records 1, 2, 3 and so on, each a piece of the original sealed with AES-GCM, ciphertext followed by its 16-byte tag. Every chunk except the last holds exactly the chunk size; the last holds the rest (anything from nothing to a full chunk) and is sealed with flag 1. An empty file has one empty last chunk.
- Messages from encrypt text use the same format with no metadata record, encoded as base64 in 64-character lines between
-----BEGIN STOUTNOOK MESSAGE-----and-----END STOUTNOOK MESSAGE-----.
When decrypting, this page refuses headers that ask for more than 256 MiB of memory, more than 10 passes, more than 8 lanes or chunks larger than 16 MiB, so a crafted file can't freeze your browser.
A Python script that decrypts it
This script decrypts files and messages made here. We tested it with Python 3.13, argon2-cffi 25.1 and cryptography 50 on files made by this page, including empty files, files of several chunks, files made with other Argon2 settings and messages pasted from emails, and checked that it rejects wrong passwords and damaged files. Save it as stoutnook_decrypt.py, run pip install argon2-cffi cryptography, then python stoutnook_decrypt.py "report.pdf.stoutnook". It asks for the password and writes the original file, under its original name, in the current folder. For an encrypted message, the text is printed on screen instead.
#!/usr/bin/env python3
"""Decrypt a StoutNook file or text message (format version 1).
Usage: python stoutnook_decrypt.py FILE [OUTPUT]
Needs: pip install argon2-cffi cryptography
"""
import base64, getpass, io, json, os, struct, sys, unicodedata
from argon2.low_level import Type, hash_secret_raw
from cryptography.exceptions import InvalidTag
from cryptography.hazmat.primitives.ciphers.aead import AESGCM
BEGIN = b"-----BEGIN STOUTNOOK MESSAGE-----"
END = b"-----END STOUTNOOK MESSAGE-----"
def stop(message):
sys.exit("stoutnook: " + message)
def safe(name):
name = os.path.basename(str(name).replace("\\", "/"))
name = "".join(c for c in name if c.isprintable() and c not in '<>:"|?*')
return name.strip(" .") or "decrypted-file"
def main():
sys.stdout.reconfigure(errors="backslashreplace")
if len(sys.argv) not in (2, 3):
stop("usage: stoutnook_decrypt.py FILE [OUTPUT]")
src = open(sys.argv[1], "rb")
size = os.fstat(src.fileno()).st_size
if BEGIN in src.read(65536): # an encrypted text message
src.seek(0)
body = src.read().split(BEGIN, 1)[1].split(END, 1)[0]
lines = [line.lstrip(b"> \t") for line in body.splitlines()]
data = base64.b64decode(b"".join(b"".join(lines).split()))
src, size = io.BytesIO(data), len(data)
src.seek(0)
head = src.read(48)
if head[:7] != b"STOUTNK":
stop("not a StoutNook file")
if len(head) < 48 or head[7] != 1 or head[8] != 1:
stop("damaged header or unsupported format version")
lanes = head[9]
memory, passes = struct.unpack(">II", head[10:18])
salt, prefix = head[18:34], head[34:42]
chunk, meta = struct.unpack(">IH", head[42:48])
if not (1 <= lanes <= 8 and 8 * lanes <= memory <= 262144
and 1 <= passes <= 10 and 1024 <= chunk <= 1 << 24
and meta <= 4096 and meta != 1):
stop("settings outside the safe limits")
password = getpass.getpass("Password: ")
password = unicodedata.normalize("NFC", password).encode()
key = hash_secret_raw(password, salt, time_cost=passes,
memory_cost=memory, parallelism=lanes,
hash_len=32, type=Type.ID)
aes = AESGCM(key)
def unseal(counter, flag, sealed):
nonce = prefix + struct.pack(">I", counter)
return aes.decrypt(nonce, sealed, head + bytes([flag]))
name, data_len, opened = None, size - 48, False
out, part = io.BytesIO(), None
try:
if meta:
record = unseal(0, 2, src.read(meta + 16))
opened, data_len = True, data_len - meta - 16
length = struct.unpack(">H", record[:2])[0]
name = json.loads(record[2:2 + length]).get("name")
target = sys.argv[2] if len(sys.argv) == 3 else name and safe(name)
if target:
if os.path.exists(target):
stop(target + " already exists")
part = target + ".part"
out = open(part, "wb")
stride = chunk + 16
count = max(1, -(-data_len // stride))
for i in range(count):
flag = 1 if i == count - 1 else 0
out.write(unseal(i + 1, flag, src.read(stride)))
opened = True
except InvalidTag:
if part:
out.close()
os.remove(part)
stop("the file is damaged or incomplete" if opened else
"wrong password, or the file was changed or damaged")
if part:
out.close()
os.replace(part, target)
print("Decrypted to " + target)
else:
sys.stdout.buffer.write(out.getvalue())
main()
Frequently asked questions
Is it safe to encrypt a file online?
It depends on where the encryption happens. Many "online" tools upload your file to their server. This one encrypts it in your browser, on your device, so the file and password never leave it. You can load the page, disconnect from the internet and it still works.
What happens if I forget the password?
The file can't be opened. There is no reset link, no master key and no backdoor, for us or anyone else; that's what makes the encryption worth having. Save the password in a password manager, or write it down and keep it somewhere safe, before you delete the original.
How do I send an encrypted file to someone?
Send the encrypted file any way you like: email, a cloud storage link or a USB stick. Then give them the password a different way, such as a phone call, a text message or in person. They open the file on this page; they don't need an account or any software.
Can I open the encrypted file without this website?
Yes. The format is documented on this page, and the Python script under "Decrypt without this site" opens files and messages on any computer with Python. Keep a copy of it with your backups.
Does encryption hide the file name and size?
The original name is stored inside the encrypted data. The encrypted copy is named after the original (photo.jpg.stoutnook) unless you switch on "Hide the file name". The size can't be hidden: the encrypted file is about 320 bytes plus 16 bytes per megabyte larger than the original.
Is AES-256 secure?
Yes. AES is the encryption standard published by the US National Institute of Standards and Technology and used for HTTPS, disk encryption and messaging apps. There is no known practical attack on AES-256 used correctly. The weak point is almost always the password, which is why the length of yours matters so much.
Can I encrypt a whole folder?
Put the folder in a ZIP file first (right-click it and choose Compress on Windows or macOS), then encrypt the ZIP file here. When it is decrypted, unzip it to get the folder back.
More free tools
- Password GeneratorStrong random passwords and passphrases.
- Password Strength CheckerHow long a password would take to crack.
- Password Leak CheckIs your password in a known data breach?
- File ChecksumVerify a download with SHA-256 or MD5.
- Link Safety CheckerSpot fake and dangerous links before you click.
- SPF CheckerValidate a domain's SPF record.
- DKIM CheckerFind and check a DKIM key by selector.
- DMARC CheckerSee and explain a domain's DMARC policy.
- MX LookupWhich servers receive a domain's email.