Introduction & Encryption

Cryptography

Encryption algorithms transform data to protect its confidentiality. Data that has not been encrypted is called plaintext; encrypting the plaintext produces ciphertext; decrypting the ciphertext recovers the original plaintext. Cryptography is the study of these operations, and almost every online service relies on it somewhere in its design — not just for obviously sensitive data, but for the plumbing (session tokens, TLS connections, password storage) that everything else sits on top of.

Encryption Keys

Most encryption algorithms use a key — often just a sequence of random bits — to encrypt and decrypt data. In a symmetric-key algorithm, the same key is used for both operations. In an asymmetric-key algorithm, different keys are used for encryption and decryption; the section on asymmetric encryption below covers why that distinction matters in practice.

Security Through Obscurity vs. Open Design

With a well-designed encryption algorithm, it should be difficult or impossible to decrypt the ciphertext without the key — even if the attacker knows the algorithm itself. This is Kerckhoffs's principle, and it is worth taking seriously rather than treating as a nice-to-have: keeping an algorithm secret might feel like it buys extra safety, but that secrecy cannot survive contact with distribution. Software gets decompiled; hardware gets reverse-engineered. An algorithm whose security depends on nobody ever working out how it functions is not secure, it is merely unexamined — and the moment it ships, in any form, that assumption is gone.

One-Time Pad (OTP)

One of the simplest encryption methods, and a useful way to build intuition for the rest of this page, is the one-time pad. Recall the bitwise XOR operation:

  • 0 XOR 0 = 0
  • 0 XOR 1 = 1
  • 1 XOR 0 = 1
  • 1 XOR 1 = 0

XOR has a property that makes it useful for encryption: applying the same value twice cancels out, i.e. x XOR y XOR y = x. So if a plaintext bitstring p is XORed with a random key k of the same length to produce ciphertext c = p XOR k, then XORing that ciphertext with the same key recovers the plaintext: c XOR k = (p XOR k) XOR k = p. Encryption and decryption are the same operation, and if the key really is uniformly random and never reused, this construction gives perfect secrecy — a ciphertext produced this way is, information-theoretically, equally consistent with every possible plaintext of the same length. The catch is in that "never reused": the pad has to be as long as everything it will ever encrypt, kept completely secret, and used exactly once.

Stream Ciphers

That last requirement is what makes a one-time pad impractical: keys can only be used once, and generating a long, truly random bitstring for every message is expensive. A stream cipher solves this by using a much shorter key to seed a pseudo-random number generator, producing a stream of pseudo-random bits (the keystream) instead of a full-length random key. This is no longer information-theoretically perfect — the keystream is deterministic given the key — but it is secure enough in practice, provided it is computationally infeasible to recover the key from the keystream.

A well-known modern example is ChaCha, developed by Daniel J. Bernstein in 2008 as a modification of his earlier 2005 cipher Salsa20 [1]. ChaCha uses 256-bit keys and a sequence of add-rotate-XOR (ARX) operations to generate a pseudorandom keystream, which is then XORed with the plaintext — the same basic idea as a one-time pad, except the keystream is pseudorandom rather than truly random. Combined with the Poly1305 authenticator, ChaCha20 is the only stream-cipher-based construction among TLS 1.3's standard cipher suites; every other option is a block cipher (AES) used in an authenticated mode.

Asymmetric Key Encryption

Symmetric encryption has a fundamental bootstrapping problem: to exchange a message, sender and recipient need to share the same key, so how does the sender get that key to the recipient securely in the first place? Asymmetric (or public-key) encryption solves this by using different keys for encryption and decryption. It needs three operations:

  • KeyGen() generates a key pair (sk, pk): a private (secret) decryption key sk, and a public encryption key pk.
  • Enc(pk, m) encrypts a message m with the public key to produce a ciphertext c.
  • Dec(sk, c) decrypts c with the private key to recover the original message m.

Knowing only pk, it should be computationally infeasible to find sk, which means the recipient can safely publish pk over an insecure network for anyone to use — there is no longer a secret to smuggle across in advance.

Beyond Encryption: Digital Signatures

Encryption protects the secrecy of data, but confidentiality is not the only property cryptography can provide. Digital signatures offer authentication (the receiver can be sure who sent a message), integrity (the receiver can be sure the message was not tampered with), and non-repudiation (the sender cannot later deny having sent it). Like asymmetric encryption, digital signatures need three operations:

  • KeyGen() generates a pair (sk, vk): a private signing key sk, and a public verification key vk.
  • Sign(sk, m) signs message m with the private key, producing a signature σ.
  • Verify(vk, m, σ) checks, using the public key, whether σ really is the output of signing m with the matching private key.

Notice the roles are reversed from asymmetric encryption: there, the public key encrypts and the private key decrypts; here, the private key signs and the public key verifies. Paar and Pelzl's Understanding Cryptography covers this KeyGen/Sign/Verify formalism in depth, including RSA, ElGamal, DSA and ECDSA [2].

Using Cryptography in Practice

The practical advice for using cryptography in an application is short, and worth stating plainly rather than diluting: do not invent your own encryption algorithm; do not write your own implementation of an existing one; do not copy an implementation off a programming forum; and do not hardcode the key in your program. Choosing the right algorithm and getting the implementation details right (padding, nonce reuse, timing side-channels) is genuinely difficult even for specialists, which is exactly why the field has converged on reusing existing, audited infrastructure rather than each project rolling its own. If you are sending data over a network, use TLS. Otherwise, prefer an "opinionated" library that makes the algorithm choices for you rather than exposing a menu of options to get wrong — NaCl and libsodium are widely used examples.

Ethical Issues: Encryption

Encryption provides confidentiality for lawful and unlawful uses alike, and that tension underlies most of the genuinely hard ethical questions in this space. Is it ethical to distribute encryption software freely? To restrict its distribution by law? To imprison someone who refuses to hand over their keys to police? For a government to build in secret weaknesses so it can monitor serious criminal activity — and if so, who else might find and use that same weakness? Is it ethical for a journalist to leak information about such a weakness once discovered? For a phone manufacturer to encrypt user data so thoroughly that not even the manufacturer, the user having lost their password, or the police with a warrant can read it? For a developer to ship software that relies on cryptography without ever having it externally audited? None of these have a single correct answer, but a security professional should be able to at least state clearly which side of each they land on, and why.

Cyber Security

The UK's National Cyber Security Centre defines cyber security as the protection of information systems — hardware, software, and associated infrastructure — the data on them, and the services they provide, from unauthorised access, harm, or misuse, whether intentional or accidental.

Information Security and the CIA Triad

ISO/IEC 27000 defines information security as the preservation of three properties, often called the CIA triad [3]:

  • Confidentiality — information is not made available or disclosed to unauthorised individuals, entities, or processes.
  • Integrity — information is accurate and complete.
  • Availability — information is accessible and usable on demand by an authorised entity.

Concretely: you protect confidentiality by encrypting data and restricting access with passwords and two-factor authentication; you protect integrity by keeping checksummed backups and using digital signatures; you protect availability by storing data redundantly across networked systems. It is worth being able to picture the failure mode of each in isolation, because they genuinely can fail independently. No confidentiality: burn your data to disc and post a copy to every household in the country. No integrity: back up your data as an encrypted multi-part archive, post it to a public server, but turn your computer off before the upload finishes — whatever ends up stored is silently corrupt. No availability: store the only copy of your data on a machine with excellent RAID redundancy, in a locked room, disconnected from any network — safe from everyone, including you.

Data Security

So what does data security mean, specifically? Information is data plus an interpretation, so in the broadest sense data security is just another name for information security, and this page mostly takes that broad view. But data stored on a computer system passes through distinct states worth naming separately: at rest (not currently being used, typically on disk), in use (being processed, typically in memory), and in transit (being sent over a network). Sometimes "data security" is used more narrowly, to mean specifically data that is not in transit — it is worth checking which sense is intended when the term comes up elsewhere.

Systems, Policies and Controls

A system can include hardware, software (operating system or applications), administrators, and users. A principal is any entity that participates in a system — a microprocessor, a webserver, or a specific person are all principals. A security policy is a statement of what it means for a system and its information to be secure; a security control is a mechanism for achieving or enforcing that policy. An attacker or adversary seeks to violate the policy, causing a security failure. A vulnerability is any weakness that can lead to a security failure, particularly when exploited deliberately; an attack vector is a specific method of attack, and the attack surface is the combination of every attack vector available against a system.

Saltzer and Schroeder's Design Principles (1975)

Saltzer and Schroeder's classic paper on protection mechanisms in computer systems set out a set of principles for secure design that has aged remarkably well, and still underlies most modern security thinking [4]: economy of mechanism (keep the design as simple as possible — simple designs are easier to verify); fail-safe defaults (deny by default, grant explicitly); complete mediation (check every access, every time, not just the first); open design (the design's security should not depend on it staying secret — Kerckhoffs's principle again, generalised beyond cryptography); separation of privilege (require more than one condition to grant access); least privilege (every principal should operate with the minimum privilege necessary); least common mechanism (minimise the amount of mechanism shared between principals); and psychological acceptability (a security mechanism people find too awkward to use correctly will get worked around).

OWASP Top 10

The Open Worldwide Application Security Project maintains a regularly updated list of the most significant web application vulnerabilities by frequency and severity. The 2021 edition lists: A01 Broken Access Control; A02 Cryptographic Failures; A03 Injection; A04 Insecure Design; A05 Security Misconfiguration; A06 Vulnerable and Outdated Components; A07 Identification and Authentication Failures; A08 Software and Data Integrity Failures; A09 Security Logging and Monitoring Failures; and A10 Server-Side Request Forgery.

This module's topics map onto that list directly, which is a useful way to see how the individual pages in this section fit together: Introduction & Encryption corresponds to A02 (Cryptographic Failures); Port Scanning & Firewalls to A05 (Security Misconfiguration); Buffer Overflows & Fuzzing to memory-management issues that fall outside the current Top 10's own numbering but were previously tracked as A11; SQL Injection to A03 (Injection); and Unix Permissions to A01 (Broken Access Control).

References

  1. Bernstein, D. J. (2008). ChaCha, a variant of Salsa20. Workshop Record of SASC 2008: The State of the Art in Stream Ciphers. https://cr.yp.to/chacha/chacha-20080120.pdf
  2. Paar, C. & Pelzl, J. (2010). Understanding Cryptography: A Textbook for Students and Practitioners. Springer. Chapter 2, "Stream Ciphers", proves the one-time pad's unconditional security using the same XOR construction (c = p XOR k) as above; Chapter 10, "Digital Signatures", covers the KeyGen/Sign/Verify formalism in more depth, including the RSA, ElGamal, DSA and ECDSA schemes.
  3. ISO/IEC. (2018). ISO/IEC 27000:2018 — Information technology — Security techniques — Information security management systems — Overview and vocabulary (5th ed.). https://www.iso.org/standard/73906.html
  4. Saltzer, J. H. & Schroeder, M. D. (1975). The Protection of Information in Computer Systems. Proceedings of the IEEE, 63(9), 1278–1308. https://doi.org/10.1109/PROC.1975.9939