Last year I got frustrated.
I needed to encrypt a quick note to send over email. Every tool I found either wanted my email address, uploaded my text to their server, or had a free tier that barely worked. For an encryption tool. The irony wasn't lost on me.
So I started building. What was supposed to be one tool turned into 19. A password generator, AES-256 encryption, EXIF metadata remover, SHA-256 hash calculator, browser fingerprint test, JWT decoder, and more - all running entirely in the browser.
No server. No signup. No database. Just JavaScript and the Web Crypto API.
Here's what I learned building CyberShield Hub.
The Web Crypto API Is Surprisingly Powerful
Most developers don't realize that modern browsers ship with a full cryptographic library. The Web Crypto API gives you:
-
crypto.getRandomValues()for cryptographically secure random numbers -
crypto.subtle.encrypt()/decrypt()for AES-GCM, AES-CBC, RSA -
crypto.subtle.digest()for SHA-256, SHA-384, SHA-512 -
crypto.subtle.generateKey()for key generation
For the password generator, I use crypto.getRandomValues() to fill a Uint32Array and map values to character sets. This is the same CSPRNG that banking apps use — not Math.random().
function generatePassword(length, charset) {
const array = new Uint32Array(length);
crypto.getRandomValues(array);
return Array.from(array, (val) => charset[val % charset.length]).join('');
}
Simple. Secure. Zero dependencies.
AES-256 in the Browser - The Tricky Parts
The encryption tool uses AES-GCM (Galois/Counter Mode) which provides both confidentiality and authentication. The flow:
- User enters text + password
- Derive a key from password using PBKDF2 (100,000 iterations)
- Generate a random IV using
crypto.getRandomValues() - Encrypt with AES-256-GCM
- Return Base64-encoded result (salt + IV + ciphertext)
The tricky part? Key derivation. You can't just use the password directly as an AES key. PBKDF2 stretches it into a proper 256-bit key, making brute-force attacks on weak passwords much harder.
const keyMaterial = await crypto.subtle.importKey(
'raw',
new TextEncoder().encode(password),
'PBKDF2',
false,
['deriveKey']
);
const key = await crypto.subtle.deriveKey(
{ name: 'PBKDF2', salt, iterations: 100000, hash: 'SHA-256' },
keyMaterial,
{ name: 'AES-GCM', length: 256 },
false,
['encrypt', 'decrypt']
);
EXIF Removal Without a Server
This one was interesting. EXIF data is embedded in JPEG files following the JFIF/EXIF specification. To strip it client-side:
- Read the file as an ArrayBuffer using FileReader
- Parse the JPEG markers (they start with 0xFF)
- Identify and remove APP1 markers (0xFFE1) which contain EXIF data
- Reconstruct the file without those markers
- Create a new Blob for download
The alternative approach - drawing to a Canvas element and exporting - works but can reduce quality slightly due to re-compression. Direct marker removal preserves the original image data.
Browser Fingerprinting: The Uncomfortable Truth
Building the fingerprint test tool was eye-opening. I'm collecting the same signals that trackers use:
- Canvas rendering (draw text, read back pixel data - different GPUs produce different results)
- WebGL renderer string (exposes your exact GPU model)
- Installed fonts (via canvas measurement technique)
- Audio processing signature (AudioContext oscillator)
- Screen properties, timezone, language, plugins
Combining these produces a hash that's unique for roughly 1 in 500,000 browsers. The uncomfortable part? There's not much users can do about it. Even installing privacy extensions can make you more unique.
What I'd Do Differently
Performance. Some tools load dependencies they don't need. I should have code-split more aggressively. The CyberShield Hub loads all 19 tools upfront - lazy loading per tool would improve initial load time.
Testing. Client-side crypto is hard to test because you can't mock crypto.subtle easily. I ended up writing integration tests that actually encrypt/decrypt and verify round-trip correctness.
Documentation. I should have documented the security model earlier. Users rightfully want to verify that "client-side only" claims are true. Showing them the Network tab in DevTools helps, but an architectural doc would be better.
The Tools
Everything is free, no signup, open to anyone:
- CyberShield Hub - all 19 tools in one dashboard
- Password Generator
- AES-256 Encryption
- EXIF Remover
- Browser Fingerprint Test
If you're building client-side security tools, I'm happy to answer questions in the comments. And if you have ideas for tool #20, I'm all ears.
Top comments (0)