Imagine: you're writing the backend for a financial service, and the requirements include a line that says "encryption of data at rest and in transit." You open the library documentation and see dozens of modes, curves with incomprehensible names, and parameters that determine security strength. Intuition tells you to pick something popular, but how do you make sure you won't build a scheme that falls apart the moment conditions change? Cryptography for developers is not a set of magic functions but an engineering discipline with clear rules and expensive mistakes. In this article, we'll break down how the key mechanisms work, where they break, and how to choose a learning path without illusions.
Why cryptography is not "just calling a function"
A cryptographic primitive by itself is almost always secure — the problem is how it's applied. Take AES: the algorithm is reliable, but if you use ECB mode (electronic codebook), identical plaintext blocks will produce identical ciphertext blocks, and the data structure starts to show through. The difference between "works" and "secure" lies in the details: mode selection, key management, random number generation, the order of protocol steps.
For a developer, it's important to understand not the math of substitutions and permutations but the threat model: who we're protecting against, what an attacker can do, what leaks are acceptable. Without this, any encryption becomes a ritual.
Breaking down one task: how a practitioner builds a secure channel
Let's take a typical task: a mobile app exchanges messages with a server that cannot be read by outsiders and cannot be altered unnoticed. We need to design a protocol. Let's see how an engineer reasons and what will go wrong with incorrect decisions.
Step 1. Choosing primitives
For traffic encryption, AEAD (authenticated encryption with associated data) is usually chosen — for example, AES-GCM or ChaCha20-Poly1305. They simultaneously encrypt and verify integrity. This is important: separate encryption and separate HMAC (message authentication code) require careful composition, while AEAD does everything in one call and reduces the risk of error.
For key exchange — an asymmetric protocol on elliptic curves (ECDH), for signatures — Ed25519. These primitives are well studied and supported in standard libraries.
Step 2. Key and nonce management
In AES-GCM, you cannot reuse the same nonce value with the same key. If this happens, an attacker can recover the authentication key and forge messages. Therefore, the nonce must be unique for each encryption. In practice, a counter or random generation with sufficient length is used.
Typical mistake: taking the nonce from a simple counter that resets when the application restarts. After a restart, the counter starts over — and nonces repeat. Solution: store the counter state in secure storage or use a cryptographically secure random number generator.
Step 3. Integrity verification and party authentication
AEAD protects the message from tampering but does not authenticate the counterparty. An attacker can mount a man-in-the-middle attack if the parties do not verify certificates. Therefore, the protocol adds verification of the X.509 certificate chain and binding to the expected domain (as in TLS).
What will go wrong if done otherwise
- Using AES-CBC without a MAC. An attacker can manipulate the ciphertext and influence the decrypted plaintext (padding oracle attacks). A real-world example: a vulnerability in popular libraries where CBC was used without integrity verification allowed decrypting data byte by byte.
- Using RSA with PKCS#1 v1.5 padding for encryption. The scheme is vulnerable to side-channel attacks (Bleichenbacher). The correct approach is to use RSA-OAEP or, better, switch to ECDH.
- Storing passwords as a SHA-256 hash without a salt. A fast hash allows brute-forcing passwords at high speed. Slow functions are needed: PBKDF2, bcrypt, scrypt, or Argon2.
Where the cryptographic scheme itself breaks
Even a correctly designed system can fail when conditions change. Let's consider several scenarios.
Scenario 1. Certificate expiration
TLS certificates have a limited validity period. If not renewed in time, clients will start rejecting the connection, and the service will become unavailable. You can notice in advance through expiration monitoring — for example, regular checks via openssl s_client -connect host:443 | openssl x509 -noout -dates. If it's already too late — urgently issue a new certificate and reload the configuration. Large companies use automation for this (the ACME protocol).
Scenario 2. Key compromise
If an attacker obtains the private key, all protection collapses. Signs: anomalous activity, unusual connections. You can notice in advance if you store keys in an HSM (hardware module) or a secure storage with access auditing. If the key is already compromised — immediate rotation, certificate revocation via CRL/OCSP, and damage analysis.
Scenario 3. Algorithm obsolescence
Over time, computing power grows, and algorithms once considered secure become vulnerable. For example, SHA-1 is now not recommended for digital signatures. You can notice in advance by following IETF and NIST recommendations. If it's already too late — migrate to SHA-256 or SHA-3, reissue certificates.
Scenario 4. Quantum threat
The emergence of a sufficiently powerful quantum computer will make RSA and ECC vulnerable (Shor's algorithm). Post-quantum algorithms (e.g., lattice-based) are already being developed. Notice in advance — track NIST standards. If it's already too late — the transition to post-quantum schemes will take years, so preparation must start early.
Learning paths: self-study, courses, practice
Cryptography can be studied in different ways, and each path has a cost.
Self-study via documentation and standards. Pros: free, you can dig deep. Cons: no feedback, easy to miss important details, and cryptography mistakes often remain invisible until an incident. Time — months, result — fragmentary.
Courses and structured programs. Pros: sequence, analysis of typical mistakes, feedback from an instructor or community. Cons: cost and the need to allocate time. Result — systematic understanding and the skill to apply it in projects.
Practice in real projects. Pros: deep assimilation through solving problems. Cons: high risk of making a mistake that will be costly. Often requires a mentor.
Honest trade-off: if you're just starting out, self-study can drag on and lead to gaps. A course provides a framework and feedback but does not replace practice. Ideally, combine: take a structured course and immediately apply the knowledge in a pet project or at work under the supervision of an experienced colleague.
Who this path suits and who it doesn't
Cryptography in practice is not for everyone. It requires perseverance, attention to detail, and a willingness to understand protocols. Here's who should go for it:
- Backend and mobile developers who deal with encryption, authentication, TLS.
- Security specialists who want to understand how the mechanisms work from the inside.
- Architects making decisions about data protection.
Who shouldn't: those looking for a "silver bullet" without diving into details; those not ready to understand standards and documentation. Cryptography does not tolerate a superficial approach.
If you want to master the topic systematically and with feedback, check out the course Cryptography in Practice. It covers exactly the issues we've touched on: from choosing AEAD to key management and post-quantum threats. The course provides structure and practical examples, but remember: real skill comes with application. Start small — secure your pet project, then transfer the approaches to your work practice.
For related topics, we recommend the articles DevSecOps (SAST/DAST): How to Embed Security into CI/CD Without Breaking Development and Microservices Architecture in Practice.
You can start here: Practical Cryptography.