Skip to content
HexaTransfer
Back to blog
Encryption & Security

How Encryption Keys Work: The Foundation of File Security

Understand how encryption keys work in simple terms. Learn about key generation, exchange, and management that makes secure file sharing possible.

An encryption key is a string of random bits that locks and unlocks data. For modern file transfer, that typically means a 256-bit AES key — 32 bytes of random data generated by a cryptographically secure random number generator (CSPRNG). The same algorithm that scrambles a 10 GB video into ciphertext can unscramble it only if given the exact same key. Key security is where encryption lives or dies: a perfect AES-256 cipher is worthless if the key is weak, predictable, or exposed. This piece walks through how keys get made, shared, stored, and destroyed in real services like HexaTransfer, Tresorit, and Proton Drive.

Keys are just random numbers

A 256-bit key is 32 bytes. If you generate one in the browser, it looks like this:

const key = crypto.getRandomValues(new Uint8Array(32));
// Uint8Array(32) [183, 45, 201, 77, ...]

What makes it a "key" is how an algorithm uses it. AES-256-GCM takes a 256-bit key, expands it via a key schedule into 15 round keys, and uses those to scramble 128-bit blocks across 14 rounds. The math doesn't care where the bits came from — it just requires they be secret and unpredictable.

"Unpredictable" is the harder half. If an attacker can guess your RNG's state, they can regenerate your key. The 2006 Debian OpenSSL bug reduced key entropy to 15 bits for two years before being caught — a textbook example of what happens when randomness fails.

Cryptographically secure randomness

Browsers provide crypto.getRandomValues() which pulls from the OS's CSPRNG: /dev/urandom on Linux, BCryptGenRandom on Windows, SecRandomCopyBytes on macOS. These in turn mix multiple entropy sources — interrupt timings, disk seek times, hardware RNG chips like Intel's RDRAND.

Do not use Math.random() for keys. It's a predictable Mersenne Twister and state can often be recovered from a few outputs.

Server-side, crypto.randomBytes() in Node.js and secrets.token_bytes() in Python wrap the OS CSPRNG and are safe. The NIST SP 800-90A and SP 800-90B standards define CSPRNG requirements; Linux kernel 5.17+ uses a BLAKE2s-based design that meets them.

Symmetric keys: one key, two directions

Symmetric algorithms like AES use one key for both encryption and decryption. The key size options:

  • 128-bit — 2^128 possible values, secure for most purposes, approved for SECRET by NSA CNSSP-15.
  • 192-bit — rare, used in some government contexts.
  • 256-bit — 2^256 values, approved for TOP SECRET, current default for file transfer services.

Doubling key size doesn't double brute-force difficulty — it squares it. 2^128 is already beyond reach (the age of the universe times 10 billion with all Earth's computers). 256-bit is a hedge against quantum computers, where Grover's algorithm effectively halves symmetric key strength.

The hard problem with symmetric keys: getting the same key to both parties without anyone intercepting it.

Asymmetric keys: the pair trick

Public-key cryptography solves key distribution. Each party generates a mathematically linked key pair: a public key (shared openly) and a private key (kept secret). Anything encrypted with the public key can only be decrypted with the private key.

Common asymmetric key types:

  • RSA-2048 — 2048-bit modulus, widely supported, slow. Used in TLS certificates.
  • RSA-4096 — stronger, even slower.
  • Curve25519 (X25519) — 256-bit elliptic curve key, fast, used by Signal and WireGuard.
  • Ed25519 — 256-bit signing key, used by SSH and Git commit signing.

The private key alone is 32–512 bytes depending on the algorithm. RSA private keys are larger because they contain multiple primes; Curve25519 private keys are just 32 random bytes.

Hybrid: combine the two for real systems

No practical system encrypts large files directly with RSA. Instead, every real protocol — TLS, PGP, Age, Signal, every serious file transfer service — uses hybrid encryption:

  1. Generate a random 256-bit AES key ("session key" or "file key").
  2. Encrypt the file with AES-256-GCM.
  3. Encrypt the session key with the recipient's public key.
  4. Send both.

The recipient decrypts the session key with their private key, then uses it to decrypt the file. You get the speed of symmetric encryption and the key-distribution convenience of asymmetric.

For browser-based file transfer, the "public key" often gets replaced with the URL fragment: the sender generates a session key, embeds it in the URL after #, and the recipient's browser reads it locally. Simpler, and works without requiring recipients to have a key pair at all.

Deriving keys from passwords

Users type passwords; algorithms want uniform random bits. A key derivation function (KDF) bridges them:

  • PBKDF2-HMAC-SHA-256 — iterates a hash function. OWASP 2023 recommends 600,000 iterations. Available in Web Crypto API.
  • scrypt — memory-hard, resists GPU attacks. Parameters: N=2^17, r=8, p=1.
  • Argon2id — current best practice, winner of the 2015 Password Hashing Competition. Parameters: memory=64 MB, iterations=3, parallelism=4.

A KDF adds a salt (random, stored alongside the ciphertext) and work factor (iterations) to slow brute force. A 12-character random password through Argon2id with 64 MB memory takes a GPU farm thousands of years to exhaust. A weak password like summer2024 falls in seconds regardless of the KDF — the KDF can't add entropy that wasn't there.

Key storage: where do keys live?

Keys need to exist somewhere, and that somewhere is a security-critical decision:

  • Browser memory (session-only). The default for ephemeral file transfers. Key is generated, used, and discarded within the page load.
  • URL fragment. Shared via the link, stored in the recipient's browser history. Limited lifetime matters.
  • Local storage / IndexedDB. Persistent but accessible to any JavaScript on the origin. Risky unless encrypted with another key.
  • OS keychain — macOS Keychain, Windows DPAPI, Linux libsecret. Hardware-backed on some platforms.
  • Hardware Security Module (HSM) — YubiKey, cloud HSM (AWS CloudHSM, Azure Dedicated HSM). Keys never leave the hardware.
  • Key Management Service (KMS) — AWS KMS, Google Cloud KMS, HashiCorp Vault. Centralized, auditable, priced around $1/key/month.

For zero-knowledge file transfer, the key lives in the URL fragment and the sender's browser. The server never stores it.

Key rotation and destruction

Long-lived keys accumulate risk. Best practice is rotation:

  • TLS certificates: 90-day rotation (Let's Encrypt default), 398-day maximum for public CAs as of 2020.
  • Data encryption keys: typically rotated every 90 days to 1 year in compliant systems (PCI DSS 4.0 Requirement 3.6).
  • Master keys: rotated annually or upon personnel changes.

Destruction matters too. Simply deleting key files from disk is insufficient — SSDs may retain data in wear-leveling areas. Secure destruction requires overwriting or dedicated HSM delete commands. Cryptographic erasure — throwing away the key so the encrypted data becomes permanently unreadable — is often the cleanest approach for bulk data.

File transfer services typically use per-file keys that exist only for the transfer's lifetime (24 hours to 7 days) and get discarded along with the ciphertext at expiration.

Recognizing weak key practices

Three common failure modes to watch for:

  • Hard-coded keys in client code. If the key is the same for every user, it's not a key — it's obfuscation.
  • Keys stored alongside ciphertext on the same server or database. A breach exposes both.
  • No key rotation. Legacy systems with decade-old encryption keys have roughly a decade of accumulated breach risk.

A reputable service publishes a cryptographic whitepaper covering key generation, storage, rotation, and destruction — and submits to third-party audits by firms like Cure53 or Trail of Bits.

Putting it in perspective

For sensitive file sharing: pick a service that generates 256-bit keys client-side via crypto.getRandomValues(), embeds them only in the URL fragment (never sent to the server), supports password-derived keys via PBKDF2 or Argon2id, and auto-expires both the key and the ciphertext within 24 hours.

Try it at hexatransfer.com — free, no account, 10 GB max.

Send large files securely with end-to-end encryption

Transfer files up to 10 GB for free with end-to-end encryption. No account required. Your files are encrypted in your browser before upload — no one else can read them.

Send a file