Is your login secure? What about your API data exchange? If you can't tell AES from RSA or when to use SHA-256, the answer is no. At Meteora Web we see it every day: backends storing passwords with MD5, APIs exchanging unsigned tokens, config files with hardcoded keys. It's not malice—it's practical ignorance. And in an era where AI finds zero-days at scale (we covered it here), not knowing crypto fundamentals is a luxury no company can afford.
This guide is for developers who already write code and want a clear, no-nonsense understanding of symmetric encryption, asymmetric encryption, and hash functions. Real commands, real code, real choices.
Symmetric Encryption: The Padlock
Think of a padlock on your door. The same key locks and unlocks it. That's symmetric encryption: one secret key used to both encrypt and decrypt. It's fast, efficient, and great for large amounts of data. The problem? How do you share that key with the person who needs to decrypt, without anyone intercepting it?
AES (Advanced Encryption Standard) is the current gold standard. We use it in GCM (Galois/Counter Mode) because it provides built-in authentication: if someone tampers with the ciphertext, you'll know. Never use ECB—it's insecure.
Practical example: encrypt a file with OpenSSL
# Encrypt with AES-256-GCM (key derived from password) openssl enc -aes-256-gcm -pbkdf2 -iter 100000 -in data.txt -out data.enc -k 'myStrongPassword'Important: GCM produces a 16-byte authentication tag. If you don't verify it during decryption, you lose tamper protection.
Production use cases:
- Data at rest encryption (database, backups)
- VPNs (IPsec, WireGuard)
- Disk encryption (LUKS, BitLocker)
- TLS session encryption after asymmetric key exchange
The Achilles' heel: key exchange
You have a secret key. You need to send it to your colleague in Rome. If you send it in plaintext, anyone eavesdropping reads it. If you encrypt it with another key, you recreate the same problem. That's why we need asymmetric encryption.
Asymmetric Encryption: The Mailbox
A mailbox has a public slot (anyone can drop a letter) and a private key (only the postman opens it). Asymmetric encryption uses two mathematically related keys: a public key (encrypts) and a private key (decrypts). You never need to share your private key.
RSA was the first widely adopted algorithm, based on the difficulty of factoring large primes. Today, ECC (Elliptic Curve Cryptography) is preferred because it provides equivalent security with much shorter keys (256-bit ECC ≈ 3072-bit RSA). For digital signatures, Ed25519 is the modern choice: fast, secure, and simple to implement.
Generating an SSH key pair (Ed25519)
ssh-keygen -t ed25519 -C "your@email.com"This creates two files: id_ed25519 (private) and id_ed25519.pub (public). You authorize access to your server with the public key; you authenticate with the private key. No password required.
Encrypt a message with a public key (RSA):
# Generate RSA private key openssl genpkey -algorithm RSA -out rsa_priv.pem -pkeyopt rsa_keygen_bits:4096 # Extract public key openssl rsa -pubout -in rsa_priv.pem -out rsa_pub.pem # Encrypt echo "Sensitive data" | openssl pkeyutl -encrypt -pubin -inkey rsa_pub.pem -out ciphertext.bin # Decrypt openssl pkeyutl -decrypt -in ciphertext.bin -inkey rsa_priv.pemNote: RSA cannot encrypt data longer than the key size. For long messages, use a hybrid approach: symmetric encryption with an ephemeral key, then encrypt that symmetric key with the public key. This is exactly how TLS (HTTPS) works.
Production use cases:
- HTTPS (TLS handshake)
- Digital signatures (software, PDF, email via S/MIME or PGP)
- SSH authentication, GPG
- Symmetric key exchange (Diffie-Hellman over elliptic curves)
Hash Functions: The Digital Fingerprint
A hash function produces a fixed-length string (e.g., 256 bits) from an arbitrary input. It's a one-way street: you cannot recover the input from the hash. Two different inputs will almost certainly produce different hashes (collision resistance).
SHA-256 is the current standard (SHA-2 family). Stop using MD5 or SHA-1—they are broken. For passwords, never use plain hashes; use slow, salted functions.
Hash a file for integrity verification
sha256sum file.zipThe output is a hash. Download the same file from an official source and compare hashes. If they match, the file hasn't been tampered with.
Password hashing: bcrypt, Argon2
Hashing a password with SHA-256 is instantaneous. An attacker with a GPU can try billions of attempts per second. The solution: key derivation functions that are slow and include a random salt per user.
import bcrypt password = b"myPassword" salt = bcrypt.gensalt(rounds=12) # cost factor 2^12 iterations hash = bcrypt.hashpw(password, salt) print(hash) # b'$2b$12$...'Argon2 is the PHC winner, resistant to GPU and ASIC attacks. Using Python's argon2-cffi:
from argon2 import PasswordHasher ph = PasswordHasher(time_cost=3, memory_cost=65536, parallelism=4) hash = ph.hash("myPassword") ph.verify(hash, "myPassword") # TrueProduction use cases:
- Secure password storage (bcrypt, Argon2, scrypt)
- Message integrity (HMAC)
- Deduplication (file fingerprinting)
- Merkle trees (blockchain, Git)
- Address generation (Bitcoin)
Putting It All Together: A Real TLS Example
When you visit an HTTPS website (e.g., ours at Meteora Web), this is what happens:
1. Your browser obtains the server's public key (signed X.509 certificate).
2. It generates a temporary symmetric key (session key).
3. It encrypts the session key with the server's public key (asymmetric).
4. The server decrypts with its private key.
5. From this point, all communication is symmetrically encrypted (AES-GCM)—fast and secure.
6. Additionally, SHA-256 is used for HMAC in message authentication.
This is why you don't encrypt everything with RSA: asymmetric handles key exchange, symmetric handles the bulk. Hybrid.
Common Mistakes to Avoid
- Using ECB mode in AES—it's deterministic, identical blocks produce the same ciphertext. Use GCM or CBC with a random IV.
- Not verifying the authentication tag in GCM—an attacker can tamper with the ciphertext undetected.
- Storing private keys in Git—never. Use a vault or environment variables.
- Using fast hashes (MD5, SHA-1, plain SHA-256) for passwords—use bcrypt/Argon2 with salt and a high cost factor.
- Ignoring elliptic curves—for new implementations, prefer Ed25519 or X25519 over RSA.
What to Do Now
- Audit your existing stack: what hash function do you use for passwords? If it's not Argon2 or bcrypt, switch immediately. Minimum cost: 12 bcrypt rounds or 3 seconds on Argon2.
- Implement key rotation: private keys expire. Plan an automated rotation mechanism.
- Always enforce HTTPS: even in development. Set up Let's Encrypt certificates with auto-renewal.
- Add digital signatures to your software updates: even a simple web app benefits from signed checksums.
- Learn a standard library: in Python master
cryptography; in PHPsodium; in Nodenode:crypto. Do not roll your own crypto.
We at Meteora Web have seen too many projects fail due to trivial crypto mistakes. Understanding the difference between symmetric, asymmetric, and hash functions isn't an academic exercise—it's the foundation for building software that respects client security. And in a world where the digital divide is also geographic, providing top-tier security to everyone is a responsibility we embrace.
Sponsored Protocol