सामग्री पर जाएँ
HexaTransfer
ब्लॉग पर वापस
एन्क्रिप्शन और सुरक्षा

Web Crypto API गाइड: डेवलपर्स के लिए ब्राउज़र-नेटिव एन्क्रिप्शन

एन्क्रिप्टेड फ़ाइल ट्रांसफर ऐप बनाने के लिए Web Crypto API सीखें। AES-GCM, RSA-OAEP और ब्राउज़र की मैनेजमेंट की पूरी गाइड।

Web Crypto API (W3C के Web Cryptography API recommendation में specified, window.crypto.subtle से exposed) ब्राउज़र का native तरीका है crypto library नेटवर्क पर ship किए बिना cryptography perform करने का। यह सभी modern browsers (Chrome 37+, Firefox 34+, Safari 10.1+, Edge 79+) पर AES-GCM, AES-CBC, AES-CTR, AES-KW, HMAC, RSA-OAEP, RSA-PSS, RSASSA-PKCS1-v1_5, ECDH, ECDSA, HKDF, और PBKDF2 support करता है। File transfer applications के लिए यह इसलिए matter करता है क्योंकि ciphertext का हर byte upload से पहले client-side generate हो सकता है, जहाँ browser constant-time, audited implementation provide करता है। यह गाइड उन primitives को cover करती है जो encrypted file transfer के लिए matter करते हैं, साथ ही वो gotchas जो हर first implementation को trip करते हैं।

SubtleCrypto Promise-Based और Async है

crypto.subtle पर हर method एक Promise return करता है। यह deliberate है: crypto operations hardware या background threads पर offload हो सकते हैं, इसलिए async force करने से API को उन तरीकों से misuse होने से बचाया जाता है जो main thread को block करें। Code का आकार:

const key = await crypto.subtle.generateKey(
  { name: "AES-GCM", length: 256 },
  true, // extractable
  ["encrypt", "decrypt"]
);

दूसरा argument (true) key को extractable mark करता है, यानी इसे बाद में crypto.subtle.exportKey() से export किया जा सकता है। Long-lived keys के लिए, इसे false पर set करें ताकि raw bytes JavaScript से unreachable रहें। उन keys के लिए जो URL fragment में serialize करनी हों (HexaTransfer pattern), इसे true पर set करें।

तीसरा argument key-usages array है। ["encrypt"] से generated key decrypt करने के लिए use नहीं हो सकती, भले ही AES-GCM symmetric हो। यह separation एक compromised encryption flow को historical data decrypt करने के लिए abuse होने से रोकता है।

फ़ाइल एन्क्रिप्शन के लिए AES-GCM

AES-GCM file content का workhorse है। यह authenticated encryption with associated data (AEAD) provide करता है: ciphertext plus authentication tag plus optional associated data जो authenticated है लेकिन encrypted नहीं। File transfer के लिए, NIST SP 800-38D recommendations के अनुसार 256-bit key और 96-bit nonce per use करें।

const iv = crypto.getRandomValues(new Uint8Array(12)); // 96-bit nonce
const ciphertext = await crypto.subtle.encrypt(
  { name: "AES-GCM", iv },
  key,
  plaintext
);

Output में ciphertext के साथ appended 128-bit GCM authentication tag शामिल है। Decryption automatically tag verify करता है और match न होने पर throw करता है। एक ही key के साथ nonce कभी reuse न करें; GCM की security nonce reuse पर catastrophically collapse होती है (attackers authentication key recover कर सकते हैं)। File transfer जहाँ हर file को fresh key मिलती है, random nonces safe हैं; long-lived keys के लिए, counter इस्तेमाल करें।

Password-Derived Keys के लिए PBKDF2

जब users file protect करने के लिए password type करें, password को directly AES key के रूप में use नहीं किया जा सकता। पहले PBKDF2 से run करें:

const passwordKey = await crypto.subtle.importKey(
  "raw",
  new TextEncoder().encode(password),
  "PBKDF2",
  false,
  ["deriveKey"]
);

const aesKey = await crypto.subtle.deriveKey(
  {
    name: "PBKDF2",
    salt: crypto.getRandomValues(new Uint8Array(16)),
    iterations: 600000,
    hash: "SHA-256",
  },
  passwordKey,
  { name: "AES-GCM", length: 256 },
  false,
  ["encrypt", "decrypt"]
);

OWASP का 2023 password-hashing guidance PBKDF2-SHA-256 के लिए minimum 600,000 iterations recommend करता है। 310,000 से कम current best practice से नीचे है। Salt random होना चाहिए और ciphertext के साथ stored होना चाहिए (यह secret नहीं है, बस unique होना चाहिए)।

2026 में नए code के लिए, PBKDF2 की बजाय Argon2id consider करें। Argon2 Web Crypto API में अभी नहीं है, लेकिन argon2-browser या @noble/hashes जैसी libraries JavaScript/WASM implementations provide करती हैं। Argon2id GPU attacks को PBKDF2 से बहुत बेहतर resist करता है।

Key Wrapping के लिए RSA-OAEP

ऐसे scenarios के लिए जहाँ आप किसी file की AES key को recipient की public key से encrypt करना चाहते हैं, RSA-OAEP इस्तेमाल करें। Keys generate करें:

const keyPair = await crypto.subtle.generateKey(
  {
    name: "RSA-OAEP",
    modulusLength: 4096,
    publicExponent: new Uint8Array([1, 0, 1]), // 65537
    hash: "SHA-256",
  },
  true,
  ["encrypt", "decrypt"]
);

नई keys के लिए modulusLength 4096 इस्तेमाल करें; 2048 acceptable है लेकिन quantum timelines firm होने पर deprecated होना शुरू होगा। RSA-OAEP सिर्फ small payloads encrypt करता है (अधिकतम modulusLength/8 - 2*hashLength - 2 bytes), इसलिए file contents directly encrypt करने की बजाय 256-bit AES key wrap करें।

Performance-sensitive apps के लिए, P-256 या P-384 के साथ ECDH RSA का बेहतर alternative है। Key generation एक order of magnitude तेज़ है और key sizes बहुत छोटी हैं।

बड़ी Files के लिए Streaming

2 GB file ब्राउज़र ArrayBuffer में आराम से नहीं आती। Chrome, Firefox, और Safari सभी File.stream() से Files read करने देते हैं जो ReadableStream return करती है, फिर chunks में process करें। Web Crypto API में अभी streaming encrypt/decrypt methods नहीं हैं (यह spec में gap है), इसलिए दो workarounds:

  1. Chunks में split करें (64 KB या 1 MB) और हर chunk को unique nonce से encrypt करें। Recipient order में concatenate करता है। यह पूरी file पर true AEAD खोता है लेकिन अधिकांश cases के लिए काम करता है।
  2. WASM crypto library (libsodium.js, @noble/ciphers WASM backend के साथ) इस्तेमाल करें जो XChaCha20-Poly1305 या AES-GCM-SIV जैसे streaming AEAD modes support करती है।

कुछ सौ megabytes से कम transfers के लिए, buffered AES-GCM ठीक काम करता है और कहीं ज़्यादा simple है। उससे ऊपर, memory pressure से बचने के लिए streaming ज़रूरी हो जाती है।

Key Export, Import, और URL Fragments

HexaTransfer-style flows के लिए जहाँ key URL fragment में travel करती है:

const rawKey = await crypto.subtle.exportKey("raw", aesKey);
const keyBase64 = btoa(String.fromCharCode(...new Uint8Array(rawKey)));
// Share URL like https://example.com/file/abc123#key=keyBase64

URL fragments HTTP requests में servers को कभी नहीं भेजे जाते (browser उन्हें strip करता है)। यह key को client-side रखता है भले ही user link share करे। Recipient side पर:

const keyBase64 = window.location.hash.slice(5); // "#key=" strip करें
const rawKey = Uint8Array.from(atob(keyBase64), c => c.charCodeAt(0));
const key = await crypto.subtle.importKey(
  "raw", rawKey, "AES-GCM", false, ["decrypt"]
);

URL encoding issues से बचने के लिए base64url encoding इस्तेमाल करें (+ को - से, / को _ से replace करें, padding strip करें)।

आम गलतियाँ

Salts या IVs के लिए Math.random() इस्तेमाल करनाMath.random() cryptographically secure नहीं है। हमेशा crypto.getRandomValues() इस्तेमाल करें।

एक ही key के साथ IVs reuse करना। GCM की security properties nonce reuse पर पूरी तरह fail होती हैं। Random 96-bit nonces एक ही key के तहत ~2^48 encryptions के बाद collide होते हैं (birthday bound)। File transfer जहाँ हर file की अपनी key है, safe; long-lived keys के लिए, counter इस्तेमाल करें।

HTTPS भूलनाcrypto.subtle सिर्फ secure contexts (HTTPS या localhost) में available है। Insecure origin पर crypto.subtle undefined है।

Extractable keys को IndexedDB में unprotected store करना। अगर keys persist करनी हों, store करने से पहले उन्हें wrap करें (जैसे, passphrase-derived key से)। Raw AES keys कभी localStorage में store न करें, जो origin पर किसी भी script को accessible है।

PBKDF2 के बिना user-supplied passwords trust करना। UTF-8 bytes में convert किया raw password 256-bit key नहीं है। हमेशा derive करें।

Authentication tags verify न करनाcrypto.subtle.decrypt() AES-GCM के लिए यह automatically करता है, लेकिन अगर आप custom protocols implement करें, तो check skip न करें।

Browser Support Nuances

सभी major browsers HTTPS पर Web Crypto support करते हैं। कुछ quirks:

  • Safari का PBKDF2 वर्षों तक Chrome/Firefox से slower था; gap Safari 15 में close हुई।
  • Firefox stricter input validation enforce करता है; Chrome में run होने वाला code Firefox में OperationError throw कर सकता है। दोनों में test करें।
  • Service workers में Web Crypto काम करता है लेकिन registration scope HTTPS होना ज़रूरी है।
  • Node.js Node 15 से require("crypto").webcrypto compatible API के साथ provide करता है, isomorphic crypto code के लिए useful।

Library की बजाय कब

Web Crypto basics को अच्छी तरह cover करता है लेकिन ChaCha20-Poly1305, Argon2, X25519, और Ed25519 जैसे modern primitives में कमी है। उनके लिए libsodium.js (WASM via) या @noble/ciphers / @noble/curves (pure JavaScript, audited) leading options हैं। HexaTransfer Web Crypto primitives directly AES-GCM और PBKDF2 के लिए इस्तेमाल करता है क्योंकि वे file transfer path को dependencies के बिना cover करते हैं।

एक पूरे encrypted transfer flow के लिए, Web Crypto आपको 100 lines से कम code में वहाँ पहुँचाता है: AES key generate करें, derive या random, file encrypt करें, ciphertext upload करें, fragment में key के साथ link share करें, recipient key import करे और decrypt करे। यही सब कुछ है।

hexatransfer.com पर आज़माएं — मुफ्त, बिना अकाउंट, 10 GB तक।

एंड-टू-एंड एन्क्रिप्शन के साथ बड़ी फ़ाइलें सुरक्षित रूप से भेजें

एंड-टू-एंड एन्क्रिप्शन के साथ 10 GB तक की फ़ाइलें मुफ़्त में ट्रांसफ़र करें। अकाउंट की आवश्यकता नहीं। अपलोड से पहले आपकी फ़ाइलें ब्राउज़र में एन्क्रिप्ट की जाती हैं — कोई और उन्हें पढ़ नहीं सकता।

फ़ाइल भेजें