Skip to content

AES Encryption Tool — GCM, CBC & CTR

Free online AES encryption — AES-128/192/256, GCM/CBC/CTR, passphrase (PBKDF2) or raw key. Runs 100% in your browser; nothing is uploaded.

No Tracking Runs in Browser Free
Everything runs in your browser — your key and data never leave this page.
Recommended
Key size
Key type
Advanced options
Ciphertext
Need the dedicated decrypt page?
Reviewed for cryptographic accuracy against FIPS 197, NIST SP 800-38D, OWASP, and the W3C Web Crypto specification — Go-Tools Security Team · Jul 16, 2026

What Is AES Encryption?

AES (the Advanced Encryption Standard) is a symmetric block cipher standardized by NIST in FIPS 197 in 2001, based on the Rijndael design by Joan Daemen and Vincent Rijmen. It encrypts data in fixed 128-bit blocks using a 128-, 192-, or 256-bit key, and the same key both encrypts and decrypts. It is the workhorse of modern cryptography, protecting everything from HTTPS traffic to disk encryption.

A raw block cipher only scrambles one 16-byte block, so AES is always run inside a mode of operation that chains blocks together. This tool offers three, all provided natively by the browser's Web Crypto API: GCM, CBC, and CTR. GCM (Galois/Counter Mode, NIST SP 800-38D) is the recommended default because it is authenticated — it produces a 128-bit authentication tag alongside the ciphertext, so any tampering is detected when you decrypt. CBC and CTR provide confidentiality only; on their own they cannot tell you whether the ciphertext was altered, which is why TLS 1.3 (RFC 8446) dropped every CBC cipher suite in favor of authenticated modes like GCM.

You will notice there is no ECB mode here, and that is deliberate. ECB encrypts every identical plaintext block to the same ciphertext block, so large-scale structure leaks straight through — the famous 'ECB penguin' image is still visibly a penguin after encryption. The Web Crypto API omits ECB for exactly this reason (it implements only AES-CBC, AES-CTR, and AES-GCM), and so do we. If you need to interoperate with a legacy system that used ECB, treat that as a reason to migrate it, not to reproduce the weakness.

Because most people type a passphrase rather than a 32-byte random key, the tool derives the AES key from your passphrase with PBKDF2-HMAC-SHA256 at 600,000 iterations and a 16-byte random salt, matching the current OWASP Password Storage guidance (and NIST SP 800-132, which requires a salt of at least 128 bits). That makes brute-forcing a weak passphrase slow, but it is not magic: this is a tool for learning modes, debugging ciphertext, and one-off personal data — not for protecting production secrets, which belong in a dedicated key-management system. For a strong passphrase, generate one with our random password generator; for a real random key, use the secret key generator.

// AES-256-GCM with a passphrase (PBKDF2-HMAC-SHA256, 600,000 iterations).
// Identical code runs in the browser and in Node.js 20+ via Web Crypto.
async function aesGcmEncrypt(plaintext, passphrase) {
  const enc = new TextEncoder();
  const salt = crypto.getRandomValues(new Uint8Array(16));
  const iv = crypto.getRandomValues(new Uint8Array(12));
  const baseKey = await crypto.subtle.importKey(
    'raw', enc.encode(passphrase), 'PBKDF2', false, ['deriveKey']);
  const key = await crypto.subtle.deriveKey(
    { name: 'PBKDF2', salt, iterations: 600000, hash: 'SHA-256' },
    baseKey, { name: 'AES-GCM', length: 256 }, false, ['encrypt']);
  const ct = new Uint8Array(await crypto.subtle.encrypt(
    { name: 'AES-GCM', iv }, key, enc.encode(plaintext)));
  const packed = new Uint8Array([...salt, ...iv, ...ct]); // salt(16) | iv(12) | ct+tag
  return btoa(String.fromCharCode(...packed));            // self-contained Base64
}

Key Features

GCM authenticated encryption by default

GCM produces the ciphertext plus a 128-bit authentication tag, so decryption fails loudly if a single byte was changed. CBC and CTR are one click away for when you need to interoperate with them.

Self-contained ciphertext

Passphrase mode packs the random salt, IV, and tag into one Base64 string, so whoever decrypts needs only the passphrase — there are no separate fields to copy or lose.

Passphrase or raw key

Type a passphrase (stretched with PBKDF2-HMAC-SHA256, 600,000 iterations) or paste an exact 128/192/256-bit key as hex or Base64, with a live byte-count badge that confirms the length.

OpenSSL-compatible output

Switch on OpenSSL mode to emit the Salted__ format that the openssl enc command and CryptoJS read, with the equivalent CLI command shown live so you can reproduce it in a terminal.

100% in your browser

Every byte is encrypted locally with the Web Crypto API. Open your Network tab and you will see nothing leave the page — it even works offline.

Base64 or Hex output

Copy the result in whichever encoding your target system expects, and inspect the salt, IV, ciphertext, and tag lengths in the segment breakdown strip.

AES Encryption Examples

GCM + passphrase (self-contained, non-deterministic)

The quick brown fox jumps over the lazy dog.
salt (16 B) + IV (12 B) + ciphertext + tag (16 B), Base64-encoded — a new value on every run

With Mode GCM, Key size 256, Key type Passphrase and the passphrase hunter2, this sentence encrypts to a single self-contained Base64 string. Encrypt it twice and you will get two completely different outputs — that is intentional. Passphrase mode generates a fresh 16-byte salt and a fresh 12-byte IV for every encryption, so identical plaintext never produces identical ciphertext and an observer cannot tell that two messages are the same. The segment strip under the output shows the exact layout: salt, then IV, then the ciphertext with its 128-bit GCM tag appended. To decrypt, the recipient needs only the passphrase and the same mode and key size — the salt, IV, and tag all travel inside the string.

OpenSSL-compatible output (CBC + passphrase)

Attack at dawn!
U2FsdGVkX18AESIzRFVmd1PBwxIFQpF+VgIhTK0aDHQ=

Switch on OpenSSL-compatible mode with Mode CBC, Key type Passphrase, the passphrase correct-horse, KDF PBKDF2 and 10,000 iterations. The tool then emits the OpenSSL Salted__ format: Base64 that always starts with U2FsdGVkX1, which is the Base64 encoding of the 8-byte Salted__ header. Because a fresh random 8-byte salt is generated each time, the exact string changes on every run, but every one decrypts on the command line with: echo 'U2FsdGVkX18AESIzRFVmd1PBwxIFQpF+VgIhTK0aDHQ=' | openssl enc -d -aes-256-cbc -pbkdf2 -iter 10000 -pass pass:correct-horse -base64 -A — which prints Attack at dawn!. Choose EVP-MD5 instead of PBKDF2 to match CryptoJS or OpenSSL 1.0.2 and older. Note that openssl enc has no GCM support, so OpenSSL mode is CBC-only.

How to Encrypt Text with AES

  1. 1

    Pick a mode and key size

    Leave Mode on GCM (recommended) and Key size on 256 for the strongest sensible default. Switch to CBC or CTR only if a system you are targeting requires it.

  2. 2

    Choose passphrase or raw key

    Keep Key type on Passphrase and enter a strong passphrase, or switch to Raw key and paste an exact 128/192/256-bit key as hex or Base64. The byte-count badge confirms whether your raw key is a valid length.

  3. 3

    Enter the text to encrypt

    Type or paste your plaintext. Encryption runs automatically as you type, entirely in your browser — no button round-trip and no upload.

  4. 4

    Copy the self-contained ciphertext

    The Base64 result on the right already contains the salt, IV, and authentication tag. Use the segment strip to see the byte layout, then click Copy. Switch the output encoding to Hex if your target system expects it.

  5. 5

    Decrypt it back when you need to

    Give the ciphertext, the passphrase, and the same mode and key size to the recipient, or open the AES decrypt page to reverse it yourself.

Common AES Encryption Mistakes

Confusing a passphrase with a raw key

A raw key must be exactly 16, 24, or 32 bytes of random data (entered as hex or Base64); a passphrase is any text and must be stretched by a KDF first. Selecting Raw key and pasting a human passphrase either errors on length or produces a weak key.

✗ Wrong
Key type: Raw key
Key (hex): correct horse battery staple   (not hex, not 32 bytes)
✓ Correct
Key type: Passphrase
Passphrase: correct horse battery staple   (stretched with PBKDF2)

Reusing an IV with the same key

The IV must be unique per message under a given key. Reusing it is fatal for GCM (it can leak the authentication key) and breaks confidentiality for CBC and CTR. Let the tool generate a fresh random IV every time.

✗ Wrong
// same key, same IV for two messages
encrypt(key, iv, a); encrypt(key, iv, b);
✓ Correct
// fresh random IV each time (the default)
encrypt(key, randomIV(), a);

Losing the salt, IV, or tag

If you copy only the ciphertext bytes and drop the prepended salt/IV — or the appended GCM tag — the data can never be decrypted. Keep the whole self-contained string, not just the middle of it.

✗ Wrong
stored = ciphertext              // salt + IV + tag thrown away
✓ Correct
stored = salt + iv + ciphertext + tag   // the full Base64 string

Expecting GCM output to match every run

GCM (and passphrase mode generally) uses a random salt and IV, so the same text encrypts to a different Base64 string every time. That is a security feature, not a bug — it means an eavesdropper cannot tell that two ciphertexts encrypt the same message.

✗ Wrong
assert(encrypt(msg) === encrypt(msg))   // fails — and should
✓ Correct
assert(decrypt(encrypt(msg)) === msg)   // this is what must hold

What You Can Do with AES Encryption

Learn how AES modes behave
Flip between GCM, CBC, and CTR with the same input to see how authentication, IV length, and ciphertext size change. A hands-on way to understand what NIST SP 800-38D actually specifies.
Produce ciphertext another system can read
Generate output in the OpenSSL Salted__ format (or as a raw key plus IV) so a backend, script, or teammate using openssl or a crypto library can decrypt it without friction.
Encrypt a short note or snippet
Protect a one-off piece of personal text — a recovery phrase you are moving between devices, a snippet in a support ticket — with a passphrase only you know. Not for regulated or production secrets.
Prototype an encryption format
Nail down your salt/IV/tag layout and KDF settings here before writing the code, using the segment breakdown to confirm the byte order and lengths.
Generate test vectors
Create known ciphertext with a fixed passphrase and mode to feed your own decryption tests, then verify the round-trip on the AES decrypt page.

AES Modes & Key Derivation

GCM (Galois/Counter Mode) — authenticated, recommended
Confidentiality plus a 128-bit authentication tag (NIST SP 800-38D). It uses a 96-bit (12-byte) IV, generated randomly per encryption, and both encryption and decryption parallelize well. The one rule you must never break: never reuse an IV with the same key. SP 800-38D limits a single key to about 2^32 randomly generated IVs, and a repeat leaks the XOR of two plaintexts and can even expose the authentication key that protects the tag. Best for almost everything.
CBC (Cipher Block Chaining) — confidentiality only
Each block is XORed with the previous ciphertext block, using a random 16-byte IV. It has no built-in authentication, so it must be paired with a separate MAC — encrypt-then-MAC, for example with our HMAC generator — and it is historically prone to padding-oracle attacks (Vaudenay, EUROCRYPT 2002). Offered here for interoperability with OpenSSL and older systems.
CTR (Counter) — confidentiality only, stream-like
Turns AES into a stream cipher by encrypting a counter, so any byte length works without padding and blocks parallelize freely. Like CBC it provides no integrity on its own, and reusing the counter/IV under one key is catastrophic. Useful when you need random access or streaming semantics.
ECB — not offered (by design)
Electronic Codebook encrypts each block independently, so identical plaintext blocks produce identical ciphertext and patterns leak — the notorious 'ECB penguin'. The Web Crypto API deliberately does not implement it, and neither do we. If a legacy peer requires ECB, treat that as a bug to fix rather than a format to reproduce.
Key derivation: 600,000 vs 10,000 vs 1 iteration
In the default passphrase mode this tool uses PBKDF2-HMAC-SHA256 at 600,000 iterations (the same SHA-256 hash applied hundreds of thousands of times) with a 16-byte salt, per OWASP. In OpenSSL-compatible mode, PBKDF2 defaults to just 10,000 iterations (the openssl enc default), and the legacy EVP_BytesToKey KDF used by CryptoJS and old OpenSSL runs a single MD5 pass — orders of magnitude weaker. More iterations mean a slower brute-force per guess, which is why the modern default is so much higher. Argon2 and scrypt are stronger still but are not part of Web Crypto, so they are out of scope here; for password storage, follow OWASP and prefer Argon2id.

AES Encryption Best Practices

Prefer GCM unless a peer requires otherwise
Authenticated encryption catches tampering that CBC and CTR silently pass through. Only drop to CBC or CTR for interoperability, and add a MAC if you do.
Use a fresh random IV for every message
The tool does this automatically. If you override the IV manually, never reuse one with the same key — for GCM a repeat is catastrophic, and for CBC it breaks semantic security.
Choose strong passphrases and real random keys
PBKDF2 slows brute force but cannot rescue a weak passphrase. Generate a long passphrase with the password generator, or a true random key with the secret key generator.
Keep the salt, IV, and tag with the ciphertext
They are not secret, but decryption fails without them. This tool's self-contained format bundles all three; if you use raw-key bare-ciphertext mode, copy the IV separately and store it alongside the ciphertext.
Do not encrypt production or regulated secrets in any online tool
Even fully client-side, a browser tool is for learning, debugging, and personal one-offs. Real secrets belong in a vetted key-management system with audited key handling and rotation. AES-256 itself is strong — approved under the NSA CNSA 2.0 suite for information up to TOP SECRET — and real-world breaks come from implementation mistakes, not the cipher.

AES Encryption FAQ

Is it safe to encrypt text online?
With this tool the encryption itself happens entirely in your browser — your text, passphrase, and key never travel to a server, which you can confirm by watching the Network tab. That makes it safe for learning, debugging, and one-off personal data. It is not the right place for production secrets, regulated data, or anything under long-term key management, and that is true of any online tool: a browser page cannot give you audited key storage, rotation, or access control. Encrypt throwaway and personal things here, and keep real secrets in a dedicated system.
Can AES be decrypted without the key?
No. AES has no known practical break, so without the key or passphrase there is no shortcut — an attacker is reduced to trying keys one by one. AES-256 has 2^256 possible keys; even at a trillion trillion guesses per second you would still need vastly longer than the age of the universe to search a meaningful fraction. The realistic risks are never the cipher itself: they are a weak passphrase, a reused IV, a leaked key, or a padding oracle in a badly built system. Choose a strong passphrase and none of those apply. Anyone advertising key-free 'AES recovery' is selling a scam.
GCM vs CBC — which mode should I use?
Use GCM. It gives you confidentiality plus a built-in 128-bit authentication tag, so if a single byte of the ciphertext is altered, decryption fails instead of silently returning corrupted data. CBC only hides the data; on its own it cannot detect tampering and has a long history of padding-oracle vulnerabilities (Vaudenay, EUROCRYPT 2002), which is why TLS 1.3 (RFC 8446) removed every CBC cipher suite. The only good reason to pick CBC here is interoperability with an existing system — for example OpenSSL's enc command, which has no GCM support.
AES-128 vs AES-256 — is 256 worth it?
Both are considered secure; AES-128 is not broken and is slightly faster. AES-256 has a larger key and a bigger security margin, and it is the size approved under the NSA's CNSA 2.0 suite for information up to TOP SECRET, which is why it is a sensible default. The cost is minor — a few extra rounds per block. Unless you are optimizing a very hot path, encrypt with AES-256; the extra security headroom is essentially free in practice.
Is my data uploaded when I encrypt here?
No. All encryption runs locally through the browser's Web Crypto API (crypto.subtle), the same audited implementation your browser uses for HTTPS. Nothing you type is sent anywhere — you can open your developer tools' Network panel, encrypt something, and watch zero requests fire, or disconnect from the internet entirely and the tool still works. SubtleCrypto is only available in secure (HTTPS) contexts, which is part of why this guarantee holds.
What is the difference between a passphrase and a key?
A key is exactly 128, 192, or 256 bits of random data — for AES-256 that is 32 raw bytes, usually written as hex or Base64. A passphrase is human-typed text of any length and is not itself a key: it must be stretched into one by a key-derivation function. This tool does that automatically in passphrase mode with PBKDF2-HMAC-SHA256, 600,000 iterations, and a random salt. Mixing the two up — pasting a passphrase into the raw-key field, or vice versa — is one of the most common reasons two systems fail to agree on a ciphertext. (For signed tokens rather than encryption, see the JWT encoder.)
Can I encrypt so OpenSSL or CryptoJS can decrypt it?
Yes. Turn on OpenSSL-compatible mode (with AES-CBC and a passphrase) and the tool emits the Salted__ format that the openssl enc command and CryptoJS understand, and it shows you the exact equivalent openssl command. Pick the matching key-derivation function: PBKDF2 for modern OpenSSL (the openssl -pbkdf2 default is 10,000 iterations), EVP-SHA256 for OpenSSL 1.1+ without -pbkdf2, or EVP-MD5 for CryptoJS and OpenSSL 1.0.2 and earlier. To go the other way and read someone else's ciphertext, use the AES decrypt tool.

Related Tools

View all tools →