Cryptography is everywhere around us and it impacts directly or indirectly on every aspect of our lives, every day, even when you don't notice it.
Cryptography is used to protect the information we share on the internet. You'll also find it when you're authenticating yourself to use your phone or laptop, or swiping the badge to get into your office. Cryptography is used to secure every digital payment transaction and to guarantee contracts that are signed digitally. It is also used to protect data we store on our devices, both from unauthorized access and from accidental corruption.
Protecting secrets…
Most people, even those who are not particularly tech-savvy, know that cryptography as the science and practice of protecting messages, files, and data, such as by encrypting and decrypting them.
In fact, this use of cryptography, to shield messages from adversaries, is thousands of years old. A common example is the Caesar cipher (a cipher is an algorithm used for encryption or decryption), which is named after the Roman emperor Julius Caesar; this is a classic example of a "substitution cipher," in which letters of the alphabet are substituted with one another. In the case of the Caesar cipher, each letter was shifted by three, so the letter A became D, B became E, Z became C, and so on.
Other famous historical ciphers include the Vigenère cipher, which in the 16th century first introduced the concept of an "encryption key," and then mechanical ones such as the Enigma machine, used by Nazi Germany during World War II and eventually broken by Polish and English researchers (this was also the topic of the 2014 movie The Imitation Game, which depicted the work of Alan Turing and the other researchers at Bletchley Park).
While the history of cryptography can be an interesting topic per se, and it provides invaluable lessons on common types of attacks against cryptography, all those historical ciphers are considered broken and so are not useful to modern application developers. As such, we won't be spending more time talking about them in this book, but nevertheless, I encourage curious readers to learn more about them!
…and the other uses of modern cryptography
Despite the strong association with ensuring confidentiality and hiding secrets, modern cryptography is used for much more than that.
In fact, throughout this book, we'll be using cryptographic functions for a variety of purposes, some of which are meant to be shared with the public rather than kept as secrets:
- In Chapter 3, File and Password Hashing with Node.js, we'll learn about hashing, which is a one-way cryptographic operation that allows you to derive a fixed-length digest for any message. This is used for purposes including checking the integrity of files or messages, generating identifiers and encryption keys, and protecting passwords.
- In Chapter 4, Symmetric Encryption in Node.js, and Chapter 5, Using Asymmetric and Hybrid Encryption in Node.js, we'll look at data encryption and decryption using various kinds of ciphers.
- In Chapter 6, Digital Signatures with Node.js and Trust, we'll learn how cryptography can be used to create and validate digital signatures, which can be used (among other things) to authenticate the author of a message, certifying its provenance, or preventing repudiation.
Why this matters to developers
As a software developer, understanding the practices presented above can help you build applications that implement cryptographic operations safely, using the most appropriate solutions. There are many possible uses of cryptography, and the aforementioned list contains only some examples.
Not all the operations we're going to learn about in this book will be useful or even relevant for every application you might be working on. However, the topics presented in the next chapters are possibly the most common ones, which developers can leverage to solve frequent real-world problems.
In fact, given the current state of application development, nowadays you could argue that knowing how to safely implement the solutions described in this book should be a skill most developers need to be at least somehow familiar with, without the need to consult with expert cryptographers.
Globally, cyberattacks have been getting more and more frequent every year and are carried out by increasingly more sophisticated adversaries, sometimes including state-sponsored actors. Just as attacks have increased in both quantity and quality, thanks to the pervasiveness of digital systems in our businesses and lives, the impact of breaches has grown costlier, with damage that can be in the range of millions of dollars and, in certain cases, catastrophic or fatal.
Whereas security used to be an afterthought in the software development life cycle, at times relegated to an issue for operations specialists only, teams are now tasked with considering it during every stage of the development process. Many organizations are also adopting practices such as DevSecOps and "shift left security," in which the security needs of an entire solution are included in the entire software development life cycle, from planning and development to operations.
DevOps and DevSecOps
DevOps is a set of principles and practices, aided by specialized tools, to enable the continuous delivery of value to end users. DevOps is built around practices such as Continuous Integration (CI) and Continuous Delivery (CD), agile software development, and continuous monitoring that are meant to bring the development and operations teams closer together and allow faster application release cycles, and continuous learning and improvement.
To learn more about DevOps, visit https://bit.ly/crypto-devops
Building on DevOps, DevSecOps requires the integration of security practices and thinking into every stage of the DevOps process – planning, building, delivering, and operating. Organizations that adopt DevSecOps believe that security is a shared responsibility among every person and team that has any dealing with an application.
To learn more about DevSecOps, visit https://bit.ly/crypto-devsecops
For example, whereas corporate or Local Networks (LANs) were traditionally considered safe, it's now common practice to assume your systems have been breached and practice defense in depth or add multiple layers of protection. So, an application that encrypts data in transit prevents an eavesdropper (called a Man-in-the-Middle or MitM) from potentially stealing secrets, even inside a LAN.
It should go without saying that while adding cryptography to your applications is often necessary to make them safe, it's almost always not sufficient. For example, protecting your users' data with strong encryption will help limit the impact of breaches but will be useless against account takeovers through social engineering.
Nevertheless, cryptography does play an important role in the process of protecting data; for example, it secures the data your application uses (both at rest and in transit), ensuring the integrity of the information stored or exchanged, authenticating end users or other services, preventing tampering, and so on.
In addition to learning about the different classes of cryptographic operations that you can take advantage of, with this book I also hope you will be equipped to understand when to use each one in the safest way possible.
In fact, just as not using cryptography can lead to serious consequences, implementing cryptography in the wrong way can be equally as bad. This can happen when developers use broken algorithms (for this reason, we'll be sticking to a few tried-and-tested ones in this book) or buggy implementations of good algorithms, such as libraries containing security vulnerabilities (which is why we're going to recommend built-in standard libraries whenever possible). In other cases, issues could be caused by developers picking the wrong cryptographic operations; one too-common example is storing passwords in databases that have been encrypted with a symmetric cipher rather than hashed, as we'll see later in the book.
Lastly, I would like to point out that the five classes of cryptographic operations we're covering in this book do not represent all the different algorithms and protocols that can be used by modern applications, nor all the possible different uses of cryptography.
For example, end-to-end encrypted messaging apps or VPNs often need to implement special key exchange algorithms, or full-disk encryption apps may leverage different algorithms or modes of operation than the ones we'll be looking at. Such problems tend to be more specific to a certain domain or type of application, and if you are building a solution that requires them, you might need to perform some additional research or work with a cryptographer.
What this book is about – and what it's not
This book is about the practical uses of common cryptographic operations that software developers without a background in cryptography can leverage.
In each chapter, we'll present a specific class of cryptographic operations, and for each, we'll then look at the following:
- What it's used for and what it should not be used for.
- What the most common algorithms are that developers should use.
- Considerations on what parameters to set for using the algorithms safely, when appropriate.
- Lastly, we'll look at sample code implementing the specific algorithms, written in JavaScript for execution on Node.js (with a nod to cryptography in the browser in the last two chapters).
Just as we have covered what this book is about, it's important to also mention what this book is not about, listing four things that you will not be learning in the following chapters:
- First, this book is not about how cryptographic algorithms work, or a description of the algorithms themselves.
As we've mentioned many times already, our book's goal is not to train cryptographers but rather to help developers build better applications leveraging common cryptographic algorithms. In this book, you will not encounter formal descriptions of the algorithms and their flows, the mathematical models behind them, and so on.
- Second, following on from the previous point, we will be looking at how to use cryptographic algorithms and not at how to implement them.
The latter not only requires a deep understanding of how algorithms work but is also a dangerous minefield because of the risks associated with poor implementations. At the risk of sounding hyperbolic, an entire class of attacks could be made possible by doing things as common as using if
statements in code implementing a cryptographic algorithm.
In short, we'll leave the implementation to the experts, and we'll stick to using pre-built libraries. Whenever possible, that will be the built-in standard library of Node.js.
- Third, as mentioned previously, this book is about strong, modern cryptography only. We'll focus on a limited set of widely adopted algorithms and functions that have been "battle-tested" and are generally deemed safe by cryptographers (more on what "safe" means in the next section). Simple or historical ciphers, codes, and so on might be interesting to those wanting to learn the science of cryptography or looking for brain-teasers, but are of little practical relevance for our goal.
- Fourth, we will not be talking about the other kind of "crypto", that is, cryptocurrencies. While Bitcoin, Ethereum, and the like are indeed based on the blockchain technology, which makes extensive use of cryptography (especially hashing and digital signatures), that's where the commonality ends. Nevertheless, should you be interested in learning about how blockchains work in the future, the concepts you'll learn from this book will likely be of use to you.
Rules of engagement
Lastly, before we begin, it's important to point out that cryptography is hard; making mistakes is surprisingly easy, and finding them can be really challenging. This is true even for expert cryptographers!
You'll often hear two very strong recommendations that are meant to keep you and the applications you're building safe. If you allow me, I propose that we turn them into a kind of "Hippocratic oath," which I invite you to repeat after me:
- I will not invent my own cryptographic algorithms.
- I will not roll my own implementation of cryptographic algorithms.
Thankfully for us, a lot of very brilliant cryptographers have worked for decades to design strong algorithms and implement them correctly and safely. As developers, the best thing we can do is to stick to proven, tested algorithms, and leverage existing, audited libraries to adopt them. Normally, that means using whatever is available on the standard library of the language you're using, the APIs exposed by the operating system or runtime environment, or leveraging well-known, audited libraries.
As we've now introduced the topic and the goals of this book, and hopefully convinced you of the importance of adopting cryptography in your applications, we're now ready to get started with our learning, starting with setting some shared understanding.