Free tools Windows power users keep installed
One-click scans. No signup required.
iTechGuides is reader-supported. When you buy through links on our site, we may earn an affiliate commission. As an Amazon Associate I earn from qualifying purchases. Learn more
Use the Web Crypto API’s SubtleCrypto interface to encrypt browser data, but treat it as a set of low-level building blocks rather than a complete security system. For ordinary application data, generate a random AES-GCM key, use a fresh IV for every encryption, authenticate important metadata, and store a versioned envelope containing the IV and ciphertext. Use RSA-OAEP for a short secret such as an AES key—not for an entire document. Persist keys as CryptoKey objects in IndexedDB when possible, protect exported keys with wrapping, and plan recovery before users lose access.
Encryption cannot compensate for a compromised page. JavaScript delivered by an attacker, a successful XSS attack, or a malicious dependency can read plaintext before encryption or after decryption. Client-side encryption is therefore one layer in a design that also needs secure delivery, authentication, authorization, key lifecycle controls, backup and recovery, and dependency and XSS defenses.
What SubtleCrypto is—and what it is not
The Web Crypto API exposes cryptographic primitives through window.crypto.subtle (and the corresponding global in workers). MDN describes it as providing “a number of low-level cryptographic primitives” and warns that “it’s very easy to misuse them.” Correctly calling encrypt() does not prove that the surrounding protocol, key storage, identity checks, or recovery process is secure.
SubtleCrypto is available only in a secure context, normally an HTTPS page or worker. Feature-detect it at runtime instead of assuming that every browser, embedded web view, or deployment mode has the same support. A worker can perform encryption for large files or batches without blocking the user interface, while a window context is usually simpler for small records.
#1 Best Overall
- POWERFUL SECURITY KEY: The Security Key C NFC is the essential physical passkey for protecting your digital life from phishing attacks. It ensures only you can access your accounts.
- WORKS WITH 1000+ ACCOUNTS: Compatible with Google, Microsoft, and Apple. A single Security Key C NFC secures 100 of your favorite accounts, including email, password managers, and more.
- FAST & CONVENIENT LOGIN: Plug in your Security Key C NFC via USB-C and tap it, or tap it against your phone (NFC) to authenticate. No batteries, no internet connection, and no extra fees required.
- TRUSTED PASSKEY TECHNOLOGY: Uses the latest passkey standards (FIDO2/WebAuthn & FIDO U2F) but does not support One-Time Passwords. For complex needs, check out the YubiKey 5 Series.
- BUILT TO LAST: Made from tough, waterproof, and crush-resistant materials. Manufactured in Sweden and programmed in the USA with the highest security standards.
function requireWebCrypto() {
if (!globalThis.isSecureContext || !globalThis.crypto?.subtle) {
throw new Error('A secure context with Web Crypto SubtleCrypto is required');
}
return globalThis.crypto.subtle;
}
const subtle = requireWebCrypto();
Check the browsers and web views that your product actually supports immediately before release; a single universal compatibility table is not a substitute for testing your target versions.
Start with a threat model
Write down what encryption is meant to protect before selecting an algorithm. The same AES-GCM code can be appropriate for one threat and irrelevant to another.
Database or storage-service compromise
If an attacker obtains ciphertext from a database or an untrusted storage service but not the decryption key, client-side encryption can prevent direct reading of the records. The design still has to protect keys, metadata, account recovery, and access tokens. A server that can obtain the user’s key or execute trusted decryption code on demand is not blind to the data.
Accidental exposure and ordinary transport risks
Encrypting before upload can reduce the impact of logs, backups, or a storage bucket containing ciphertext. HTTPS remains necessary: it protects the page and API traffic while keys and plaintext are in use. Encryption is not a replacement for transport security, authorization, or correct server-side access controls.
Hostile or modified JavaScript
A script that is altered before it reaches the browser can capture passwords, plaintext, keys, or decrypted results. Client-side encryption does not defend against a compromised origin, a successful XSS attack, or a dependency that executes attacker-controlled code. Use a strict content security policy, minimize and review dependencies, protect deployment and release systems, and treat script integrity as part of the cryptographic boundary.
Lost devices and forgotten passwords
Strong encryption can make recovery impossible. Decide whether a second device, an administrator-held recovery key, or a user-controlled backup is allowed. Document what happens when the only decryption key is deleted; do not promise recovery that the protocol cannot provide.
Rank #2
- POWERFUL SECURITY KEY: The YubiKey 5C NFC is the most versatile physical passkey, protecting your digital life from phishing attacks. It ensures only you can access your accounts
- WORKS WITH 1000+ ACCOUNTS: Compatible with popular accounts like Google, Microsoft, and Apple. A single YubiKey 5C NFC secures 100+ of your favorite accounts, including email, password managers, and more
- FAST & CONVENIENT LOGIN: Plug in your YubiKey 5C NFC via USB and tap it, or tap it against your phone (NFC), to authenticate. No batteries, no internet connection, and no extra fees required
- MOST SECURE PASSKEY: Supports FIDO2/WebAuthn, FIDO U2F, Yubico OTP, OATH-TOTP/HOTP, Smart card (PIV), and OpenPGP. That means it’s versatile, working almost anywhere you need it
- PRIMARY & SPARE KEYS: Just like having a spare house key, we recommend buying two YubiKeys - one for daily use and one as a spare. That way you’ll never get locked out of your accounts
AES-GCM or RSA-OAEP?
These algorithms solve different problems. AES-GCM is symmetric: the same secret key encrypts and decrypts and is the normal choice for bulk data. RSA-OAEP is public-key encryption: anyone with the public key can encrypt, while only the private-key holder can decrypt. RSA-OAEP is intended for short plaintext and key-wrapping workflows.
Do these 3 things before closing this tab:
1Repair Windows errors before they cause bigger problems2Fix the driver behind crashes, sound loss and screen glitches3Clear out junk files and repair common Windows errors| Decision point | AES-GCM | RSA-OAEP |
|---|---|---|
| Cryptographic model | Symmetric encryption with one shared secret | Public-key encryption with separate public and private keys |
| Best use | Documents, records, messages, and other bulk data | A short secret, commonly an AES key |
| Message size | Designed for ordinary application payloads subject to implementation limits | Short plaintext only; MDN’s concrete example permits at most 190 bytes with a 2048-bit key and SHA-256 |
| Integrity | GCM authenticates ciphertext and optional additional authenticated data | OAEP provides encryption padding; use a complete protocol and do not treat it as a general document format |
| Key distribution | Every decrypting party needs the secret key | Encryptors need only the public key; the private key must remain protected |
| Typical performance choice | Bulk-data choice | Short-message or key-wrapping choice |
The common hybrid design is to generate one random AES-GCM key for a file or record, encrypt the data with AES-GCM, then encrypt or wrap that small AES key with RSA-OAEP for the intended recipient. Never send a large document directly to RSA-OAEP.
Implement AES-GCM correctly
1. Generate a key with an explicit policy
Generate keys with the narrowest permitted usages. A non-exportable key cannot be exported through exportKey(), which limits accidental disclosure. Persist the resulting CryptoKey directly when your storage design allows it.
const aesKey = await subtle.generateKey(
{ name: 'AES-GCM', length: 256 },
false,
['encrypt', 'decrypt']
);
The second argument is the extractable flag. Set it to true only when a documented wrapping, backup, or interoperability design requires export. A key that is technically exportable is easier to mishandle, so treat that choice as a review item.
2. Encrypt with a fresh IV and authenticated metadata
Generate a unique, unpredictable IV for every encryption under a given AES-GCM key. Store the IV beside the ciphertext; it is not a secret. If the record’s identity, tenant, version, or content type must be bound to the ciphertext, pass a canonical representation as additionalData. GCM authenticates that data but does not encrypt it.
Quick wins for a faster PC:
Repair Windows errors before they cause bigger problemsFix Now →Scan for outdated or missing drivers - takes under a minuteDriver Scan →Clear out junk files and repair common Windows errorsFree Scan →function toBase64(bytes) {
let binary = '';
for (const byte of bytes) binary += String.fromCharCode(byte);
return btoa(binary);
}
async function encryptText(key, plaintext, recordId) {
const iv = crypto.getRandomValues(new Uint8Array(12));
const aadObject = { version: 1, recordId, kind: 'text' };
const aad = new TextEncoder().encode(JSON.stringify(aadObject));
const clear = new TextEncoder().encode(plaintext);
const ciphertext = await subtle.encrypt(
{ name: 'AES-GCM', iv, additionalData: aad, tagLength: 128 },
key,
clear
);
return {
version: 1,
algorithm: 'AES-GCM',
keyId: 'current-user-key',
iv: toBase64(iv),
aad: toBase64(aad),
ciphertext: toBase64(new Uint8Array(ciphertext))
};
}
The 12-byte IV shown is a conventional GCM choice. The security requirement is uniqueness for each encryption with the same key; never reuse an IV because a repeated GCM IV can compromise confidentiality and authentication.
Rank #3
- POWERFUL SECURITY KEY: The YubiKey 5 NFC is the most versatile physical passkey, protecting your digital life from phishing attacks. It ensures only you can access your accounts
- WORKS WITH 1000+ ACCOUNTS: Compatible with popular accounts like Google, Microsoft, and Apple. A single YubiKey 5 NFC secures 100+ of your favorite accounts, including email, password managers, and more
- FAST & CONVENIENT LOGIN: Plug in your YubiKey 5 NFC via USB and tap it, or tap it against your phone (NFC), to authenticate. No batteries, no internet connection, and no extra fees required
- MOST SECURE PASSKEY: Supports FIDO2/WebAuthn, FIDO U2F, Yubico OTP, OATH-TOTP/HOTP, Smart card (PIV), and OpenPGP. That means it’s versatile, working almost anywhere you need it
- PRIMARY & SPARE KEYS: Just like having a spare house key, we recommend buying two YubiKeys - one for daily use and one as a spare. That way you’ll never get locked out of your accounts
3. Keep a versioned envelope
Do not save an unexplained byte string. Store a stable, versioned envelope that identifies the algorithm, key identifier, IV, ciphertext, and any authenticated-data or parameter identifiers. A future migration can then recognize old records and re-encrypt them deliberately.
{
version: 1,
algorithm: 'AES-GCM',
keyId: 'user-key-2026-01',
iv: 'base64...',
aad: 'base64...',
ciphertext: 'base64...'
}
Keep the envelope metadata unambiguous and canonical. If a field affects interpretation, either authenticate it as additional data or include it in the authenticated payload.
4. Decrypt without creating an oracle
Decode the envelope, reconstruct exactly the same additional data, and call decrypt(). Any modified ciphertext, wrong key, wrong IV, or mismatched authenticated data should fail. Return one generic integrity or authentication error to callers; do not reveal whether a key, IV, padding-like condition, or individual field caused the failure.
The Tool Desk
Outbyte PC Repair FREERepair Windows errors before they cause bigger problemsFix Now →Outbyte Driver Updater FREEScan for outdated or missing drivers - takes under a minuteDriver Scan →function fromBase64(value) {
const binary = atob(value);
return Uint8Array.from(binary, character => character.charCodeAt(0));
}
async function decryptText(key, envelope, recordId) {
try {
if (envelope.version !== 1 || envelope.algorithm !== 'AES-GCM') {
throw new Error('Unsupported envelope');
}
const expectedAad = new TextEncoder().encode(
JSON.stringify({ version: 1, recordId, kind: 'text' })
);
const plaintext = await subtle.decrypt(
{
name: 'AES-GCM',
iv: fromBase64(envelope.iv),
additionalData: expectedAad,
tagLength: 128
},
key,
fromBase64(envelope.ciphertext)
);
return new TextDecoder().decode(plaintext);
} catch {
throw new Error('Unable to verify or decrypt this record');
}
}
Log only non-sensitive diagnostics such as an envelope version or internal request identifier. Never log plaintext, password-derived material, raw keys, or attacker-controlled ciphertext.
Store and protect CryptoKey objects
IndexedDB persistence
CryptoKey objects support structured cloning and can commonly be stored in IndexedDB along with the envelope metadata and key identifier. Keep the key record and its metadata in a transaction where practical, and handle storage deletion as a real key-loss event. Clearing site data, changing profiles, or uninstalling an application can remove the only local copy.
Store the key object rather than exporting raw key bytes whenever the browser and your design permit. A non-exportable key reduces the number of places where sensitive material can appear, but it does not protect plaintext while the page is running.
Rank #4
- POWERFUL SECURITY KEY: The Security Key NFC is the essential physical passkey for protecting your digital life from phishing attacks. It ensures only you can access your accounts.
- WORKS WITH 1000+ ACCOUNTS: Compatible with Google, Microsoft, and Apple. A single Security Key NFC secures 100 of your favorite accounts, including email, password managers, and more.
- FAST & CONVENIENT LOGIN: Plug in your Security Key NFC via USB-A and tap it, or tap it against your phone (NFC) to authenticate. No batteries, no internet connection, and no extra fees required.
- TRUSTED PASSKEY TECHNOLOGY: Uses the latest passkey standards (FIDO2/WebAuthn & FIDO U2F) but does not support One-Time Passwords. For complex needs, check out the YubiKey 5 Series.
- BUILT TO LAST: Made from tough, waterproof, and crush-resistant materials. Manufactured in Sweden and programmed in the USA with the highest security standards.
Wrapping for backup or transfer
When a key must be exported for backup or transfer, use wrapKey() and unwrapKey() with a separately protected wrapping key instead of writing clear key bytes to storage. The wrapping key needs its own lifecycle, access policy, rotation plan, and recovery story. Test the extractability and algorithm constraints of your target browsers: some wrapping designs require the wrapped key to be exportable under the platform’s key policy.
Recommended Free Tools
Never place a raw key in local storage, a URL, analytics data, an exception report, or a server log. If a backup is user-controlled, explain that losing the wrapping password or recovery key can make every backup unreadable.
Rotation and revocation
Assign a key identifier to every envelope. During rotation, keep the old decrypting key long enough to read existing records, encrypt new records with the new key, and migrate old records in a controlled job. Revoke or destroy an old key only after the retention and recovery policy says it is safe. A key identifier is metadata, not a secret; protect the key it names.
Derive a key from a password
A password should not be used directly as an AES key. Import it as password material, derive a key with a password-based primitive, and generate a unique random salt for each independent password context. Store the salt and a versioned set of work-factor parameters beside the ciphertext. The Web Crypto API exposes derivation primitives, but it does not define one universal work factor for every device and application; choose, document, benchmark, and periodically review your policy.
async function deriveAesKey(password, salt, iterations) {
const passwordBytes = new TextEncoder().encode(password);
const material = await subtle.importKey(
'raw',
passwordBytes,
'PBKDF2',
false,
['deriveKey']
);
return subtle.deriveKey(
{
name: 'PBKDF2',
salt,
iterations,
hash: 'SHA-256'
},
material,
{ name: 'AES-GCM', length: 256 },
false,
['encrypt', 'decrypt']
);
}
- Generate a cryptographically random salt; never use a fixed application-wide salt.
- Record the derivation algorithm, hash, iteration count, and parameter version in the envelope.
- Derive the AES-GCM key only when needed and keep it in memory for the shortest practical time.
- On a successful unlock, re-derive with newer parameters and re-encrypt records when the policy version changes.
- Define what happens after a forgotten password. If no independent recovery key exists, there may be no legitimate way to decrypt the data.
Use a password-strength and rate-limiting policy at the account layer as well. A derivation function slows guessing; it does not make a weak password equivalent to a random key.
Use RSA-OAEP for short secrets
Generate or import RSA-OAEP keys with an explicit hash and modulus policy. The public key can be distributed to encryptors; the private key requires stronger protection and a recovery plan.
Best Value
- POWERFUL SECURITY KEY: The YubiKey 5 is a versatile physical passkey that protects your digital life from phishing attacks. It ensures only you can access your accounts.
- WORKS WITH 1000+ ACCOUNTS: Compatible with popular accounts like Google, Microsoft, and Apple. A single YubiKey 5 secures 100+ of your favorite accounts, including email, password managers, and more.
- FAST & CONVENIENT LOGIN: Plug in your YubiKey 5 via USB and tap it to authenticate. No batteries, no internet connection, and no extra fees required.
- MOST SECURE PASSKEY: Supports FIDO2/WebAuthn, FIDO U2F, Yubico OTP, OATH-TOTP/HOTP, Smart card (PIV), and OpenPGP. That means it’s versatile, working almost anywhere you need it.
- BUILT TO LAST: Made from tough, waterproof, and crush-resistant materials. Manufactured in Sweden and programmed in the USA with the highest security standards.
const rsaPair = await subtle.generateKey(
{
name: 'RSA-OAEP',
modulusLength: 2048,
publicExponent: new Uint8Array([1, 0, 1]),
hash: 'SHA-256'
},
false,
['encrypt', 'decrypt']
);
RSA-OAEP has a strict size limit. MDN’s documented example allows a maximum of 190 bytes for a 2048-bit RSA key using SHA-256. The exact limit depends on the modulus and hash, so do not infer a larger capacity from the key’s bit length. For a hybrid envelope, encrypt the document with AES-GCM and use RSA-OAEP only for the small AES key or another short secret.
If your implementation exports a raw AES key before RSA encryption, the AES key must have been created with an export policy that permits it. Where supported by your design, use key-wrapping APIs and keep long-lived data keys non-exportable. Test import, export, wrapping, and unwrapping across every target browser before committing to the format.
A complete implementation workflow
- Define the threat model. State whether the goal is protection from a storage breach, an untrusted storage provider, accidental exposure, or another specific event. Record the cases client-side encryption does not cover, especially hostile JavaScript.
- Establish a secure execution context. Serve the application over HTTPS, feature-detect
crypto.subtle, and decide whether workers are needed for large files or responsiveness. - Select the primitive. Use AES-GCM for bulk data. Use RSA-OAEP to protect a short symmetric key, not the document itself. Avoid treating CTR or CBC as authenticated encryption; they do not authenticate by default.
- Design the envelope. Define the version, algorithm, key identifier, IV, authenticated metadata, ciphertext, and derivation or wrapping parameters before shipping data.
- Implement key creation and storage. Prefer non-exportable
CryptoKeyobjects in IndexedDB. If backup or transfer requires export, wrap keys under a separately protected wrapping key. - Implement failure handling. Reject malformed or unsupported envelopes, return a generic integrity error, and keep sensitive values out of logs.
- Plan lifecycle operations. Specify rotation, revocation, account changes, device loss, password changes, backup restoration, and permanent key loss.
- Test adversarial cases. Modify every envelope field, reuse an IV in a test fixture to ensure detection, try wrong keys, delete IndexedDB data, exercise worker and window contexts, and verify import/export and rotation behavior.
Common failure modes and fixes
“SubtleCrypto is undefined”
The page may not be in a secure context, the runtime may be an unsupported web view, or the code may be executing in an environment without the Web Crypto API. Check isSecureContext, serve over HTTPS, feature-detect the API, and provide a clear unsupported-environment path.
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
Decryptions fail after an envelope change
Usually the producer and consumer disagree about the IV encoding, additional-data serialization, algorithm parameters, or envelope version. Define canonical serialization, authenticate the metadata that affects interpretation, and reject unknown versions instead of guessing.
Data becomes unreadable after clearing browser storage
IndexedDB is storage, not an archival guarantee. If the local key was the only copy, deletion is equivalent to key destruction. Provide an explicit wrapped backup or recovery mechanism before users depend on local-only encryption.
A developer wants to reuse one IV
Do not do so with AES-GCM. Generate a fresh IV for every encryption under the key and store it with the ciphertext. Add automated tests that make accidental reuse visible during development.
An application tries to RSA-encrypt a file
Replace the design with hybrid encryption: AES-GCM for the file and RSA-OAEP for the small AES key. Respect the documented 190-byte example limit for 2048-bit RSA with SHA-256 and calculate limits from the actual key parameters.
Error logs contain plaintext or key material
Replace detailed cryptographic exceptions with a generic failure at the application boundary. Log only non-sensitive identifiers and operational metadata, and review telemetry, crash reporting, URLs, and support tooling for accidental disclosure.
Security review checklist
- The application has a written threat model and explicitly states what a compromised JavaScript delivery path can read.
- All cryptographic operations run in a secure context, with runtime feature detection and tested target browsers.
- AES-GCM uses a unique IV for every encryption under a key and authenticates required metadata.
- Envelopes are versioned and include the algorithm, key identifier, IV, ciphertext, and relevant derivation or wrapping parameters.
- RSA-OAEP is restricted to short messages or key wrapping; large plaintext is never sent directly through RSA.
- Keys are non-exportable where feasible, and any exported material is wrapped and separately protected.
- IndexedDB persistence, site-data deletion, device changes, rotation, revocation, backup, and lost-key behavior are documented.
- Password-derived keys use unique salts and recorded, reviewable work-factor parameters.
- Decryption failures expose no plaintext, raw key bytes, or detailed oracle behavior.
- Tests cover modified ciphertext, wrong keys, malformed envelopes, IV handling, storage loss, worker execution, interoperability, and migration.
Bottom line
SubtleCrypto can provide strong browser-side encryption when it is embedded in a disciplined protocol. Choose AES-GCM for data, RSA-OAEP for short key-wrapping tasks, persist CryptoKey objects carefully, authenticate metadata, and design recovery and script-integrity controls as seriously as the encryption call itself.
Quick Recap
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

