Zum Hauptinhalt springen
•
Sichere ProgrammierungThe Jevons Paradox of Judgment(03.10.2026 um 03:12 Uhr)
•
Sichere ProgrammierungI built a game so my family could see who always gets skipped(03.10.2026 um 03:13 Uhr)
••••
Sichere ProgrammierungTrack which companies are hiring (and closing roles) with a jobs API(03.10.2026 um 03:16 Uhr)
•
Sichere ProgrammierungAI Coding Has Made Project-Switching Way Too Easy(03.10.2026 um 03:16 Uhr)
••••
Sichere ProgrammierungThe Jevons Paradox of Judgment(03.10.2026 um 03:12 Uhr)
•
Sichere ProgrammierungI built a game so my family could see who always gets skipped(03.10.2026 um 03:13 Uhr)
••••
Sichere ProgrammierungTrack which companies are hiring (and closing roles) with a jobs API(03.10.2026 um 03:16 Uhr)
•
Sichere ProgrammierungAI Coding Has Made Project-Switching Way Too Easy(03.10.2026 um 03:16 Uhr)
•••
Intelligence View
⚡ tsecurity.de Intelligence

Client-Side Encryption with Web Crypto API

Building a pure-frontend encryption toolset with no backend dependency. Web Crypto API is powerful — but has some gotchas. Why Pure Frontend Encryption? P…

Beitrag
0
Seite
0
↗ Quelle (dev.to)
Social ReaktionenReagiere als Erste:r — dein Feedback zählt!

Building a pure-frontend encryption toolset with no backend dependency.

Web Crypto API is powerful — but has some gotchas.







Why Pure Frontend Encryption?





  1. Privacy — Sensitive user data should never reach a server


  2. Trust — Open-source frontend code is auditable; black-box backends aren't


  3. Cost — Zero server cost






What Web Crypto API Supports






✅ SHA-1 / SHA-256 / SHA-384 / SHA-512 (digest)
✅ RSA-OAEP / RSA-PSS (asymmetric)
✅ AES-GCM / AES-CBC / AES-KW (symmetric)
✅ HMAC (signatures)
✅ ECDSA / Ed25519 (elliptic curve)
❌ MD5 (not in spec)
❌ Blowfish / TWOFISH (not in spec)









SHA Hash Family



Simplest usage:




async function sha256(message) {
const encoder = new TextEncoder()
const data = encoder.encode(message)
const hashBuffer = await crypto.subtle.digest('SHA-256', data)
const hashArray = Array.from(new Uint8Array(hashBuffer))
return hashArray.map(b => b.toString(16).padStart(2, '0')).join('')
}

sha256('hello')
// → "2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824"






All five hashes in one call:




async function hashAll(text) {
const encoder = new TextEncoder()
const data = encoder.encode(text)
const algorithms = ['SHA-1', 'SHA-256', 'SHA-384', 'SHA-512']
const results = {}

for (const algo of algorithms) {
const hashBuffer = await crypto.subtle.digest(algo, data)
results[algo] = Array.from(new Uint8Array(hashBuffer))
.map(b => b.toString(16).padStart(2, '0'))
.join('')
}

return results
}









MD5: Not in Web Crypto, Implement It Yourself



MD5 is a weak hash, superseded by SHA-2, but still heavily used in practice.



Web Crypto doesn't support it. Implement it yourself:




function md5(string) {
function md5cycle(x, k) {
var a = x[0], b = x[1], c = x[2], d = x[3]
a = ff(a, b, c, d, k[0], 7, -680876936)
d = ff(d, a, b, c, k[1], 12, -389564586)
// ... (full MD5 four-round computation)
x[0] = add32(a, x[0])
x[1] = add32(b, x[1])
x[2] = add32(c, x[2])
x[3] = add32(d, x[3])
}
// ... (padding, processing, hex output)
// ~100 lines total
}






The complete MD5 implementation is about 100 lines — pure bitwise operations, no dependencies.



Performance: For short text (<10KB), pure JS MD5 takes ~5-10ms. More than acceptable.






AES-GCM Encryption






// Generate random key
async function generateAesKey() {
return crypto.subtle.generateKey(
{ name: 'AES-GCM', length: 256 },
true, // exportable
['encrypt', 'decrypt']
)
}

// Encrypt
async function aesEncrypt(plaintext, key) {
const encoder = new TextEncoder()
const iv = crypto.getRandomValues(new Uint8Array(12)) // 96-bit IV

const ciphertext = await crypto.subtle.encrypt(
{ name: 'AES-GCM', iv: iv },
key,
encoder.encode(plaintext)
)

// Return IV + ciphertext (IV must be transmitted together)
const result = new Uint8Array(iv.length + ciphertext.byteLength)
result.set(iv)
result.set(new Uint8Array(ciphertext), iv.length)
return btoa(String.fromCharCode(...result)) // Base64 output
}

// Decrypt
async function aesDecrypt(encodedText, key) {
const data = Uint8Array.from(atob(encodedText), c => c.charCodeAt(0))
const iv = data.slice(0, 12)
const ciphertext = data.slice(12)

const plaintextBuffer = await crypto.subtle.decrypt(
{ name: 'AES-GCM', iv: iv },
key,
ciphertext
)

return new TextDecoder().decode(plaintextBuffer)
}









Security Best Practices





  1. Random IV every time — Same key encrypting different messages must use different IVs


  2. IV doesn't need to be secret — Transmit it alongside ciphertext


  3. GCM mode includes authentication — Tampered ciphertext fails decryption with an error


  4. Don't persist keys — Key disappears on page refresh






HMAC Signatures






async function hmacSha256(message, keyString) {
const encoder = new TextEncoder()

const key = await crypto.subtle.importKey(
'raw',
encoder.encode(keyString),
{ name: 'HMAC', hash: 'SHA-256' },
false,
['sign', 'verify']
)

const signature = await crypto.subtle.sign('HMAC', key, encoder.encode(message))

return Array.from(new Uint8Array(signature))
.map(b => b.toString(16).padStart(2, '0'))
.join('')
}

async function verifyHmac(message, keyString, expectedSignature) {
const encoder = new TextEncoder()
const key = await crypto.subtle.importKey(
'raw',
encoder.encode(keyString),
{ name: 'HMAC', hash: 'SHA-256' },
false,
['verify']
)

const signatureBytes = Uint8Array.from(
expectedSignature.match(/.{1,2}/g).map(b => parseInt(b, 16))
)

return crypto.subtle.verify('HMAC', key, signatureBytes, encoder.encode(message))
}









Performance Comparison






Size       Algorithm       Time
────────────────────────────────
1 KB SHA-256 < 1ms
1 KB MD5 (JS) ~2ms
1 KB AES-GCM encrypt ~1ms
100 KB SHA-256 ~2ms
100 KB AES-GCM ~3ms
1 MB SHA-256 ~15ms
1 MB AES-GCM ~20ms






For a tool site processing KB-level data, Web Crypto performance is more than sufficient.






MD5 Alternatives























Approach Pros Cons
Pure JS (~100 lines) No dependencies, controllable Self-maintained

blueimp-md5 library
Mature and stable Extra dependency


The project chose pure JS implementation.






Best Practices Summary





  1. Prefer Web Crypto API — Native, secure, fast


  2. Pure JS for MD5 — Small code, doesn't affect architecture


  3. Don't store keys — Gone on refresh


  4. Generate random IV — Every encryption gets a new IV


  5. Use GCM over CBC — GCM has built-in authentication


  6. HMAC for integrity — More reliable than hash alone






Project



Hash Generator — AES Encrypt/Decrypt — HMAC Generator

🔍 CTI & Forensik

Cyber Threat Intelligence & Forensik

ATT&CK-Navigator · IoC-Radar · Exploit-Belege
IoC Intelligence
1 Indikatoren · Defanged · STIX 2.1
2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824
CTI Threat Relationship Graph
Akteure · Techniken · Beziehungen
3 Knoten · 2 Relationen
CVE / Incident Threat Actor Software MITRE ATT&CK CWE Weakness IoC
Ähnliche Beiträge
🔍 Verwandte News

Auch interessante Nachrichten Client-Side Encryption with Web Crypto API

Thematisch verwandte Begriffe: ClientSide, Encryption, with, Crypto · 6 Treffer

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

💬 Kommentare werden geladen…
Zum Aktualisieren ziehen
tsecurity.de Icon
Offline-Lesen, Eilmeldungen & 0ms Ladezeit

Installiere tsecurity.de direkt auf deinen Home-Bildschirm für das ultimative Vollbild-Magazinerlebnis ohne Browser-Leisten.

Nächster Beitrag