In a recent post, we discussed what the Payment Card Industry Data Security Standard (PCI DSS) is and some common issues we see in how organizations interpret or implement specific required controls. See “Common Misconceptions around the Payment Card Industry Data Security Standard (PCI DSS)” for more information. In this post, we’ll discuss issues we often see around encryption.
First, some helpful definitions
If you are familiar with what encryption is, you can skip this section. If you need or want a quick primer on those topics, the following should help provide some context and help you understand how the various components are related. Some key terms:
- Plaintext – the data that we want to encrypt. It may not actually be human-readable, but the original data is always referred to as the “plaintext.”
- Ciphertext – the data after it has been encrypted.
- Encryption algorithm – the pre-defined process used to convert plaintext into ciphertext. The definition of this Algorithm is the same for all systems.
- Encryption key – a piece of data that informs the encryption algorithm how precisely to transform plaintext into ciphertext. This key alters how the encryption algorithm works internally, but does not change the definition of the algorithm itself.
The components of basic encryption systems
You can see that an encryption algorithm accepts two pieces of input (key and plaintext) and produces a single output (ciphertext).
In modern cryptography, it is considered best practice for the definition of the encryption algorithm itself to be public, in order to ensure that the algorithm receives close scrutiny for errors or weaknesses. In practice, this means that anyone in possession of the key can decrypt a piece of ciphertext based on that key, using the public definition of the algorithm. Therefore, in order for the system to be secure, you must prevent disclosure of the key to unauthorized parties. This is the main principle behind the PCI DSS rules related to cryptography.
The primary purpose of the PCI DSS requirements is to ensure that cardholder data (CHD) is protected from disclosure to unauthorized parties. Typically, we think of “unauthorized parties” as being criminals, but the requirements equally apply to people inside the organization who do not have a business need to see CHD. One way to help prevent unauthorized disclosure is to encrypt the data when stored, so that even if you can see the encrypted data, you cannot see the plaintext CHD without also having the ability to decrypt it. Note that those are, in theory, two separate permissions: (1) retrieve data (2) decrypt data; it is this separation of permissions that underpins the security of the overall system.
What are the requirements?
There are a total of 25 requirements that are related to the use of cryptography in PCI DSS, which can be broadly grouped into three categories of requirements:
1) Use “strong” cryptographic algorithms
This term is used repeatedly throughout the PCI DSS requirements and is defined in the PCI DSS 3.2 “Glossary of Terms” as:
Cryptography based on industry-tested and accepted algorithms, along with key lengths that provide a minimum of 112-bits of effective key strength and proper key-management practices. Cryptography is a method to protect data and includes both encryption (which is reversible) and hashing (which is “one way”; that is, not reversible.)
NIST Special Publication 800-57 Part 1 (http://csrc.nist.gov/publications/) is referenced for further information on key strengths and algorithms.
2) Protect encryption keys
As described in the previous section, the Key is the most important part of any encryption process and must be kept secret in order to ensure the confidentiality of the encrypted data. For this reason, 14 of the 25 requirements relate to how to generate, store, and replace keys, along with the policies that define all of those operations.
3) Secure data during both transmission and storage
Encrypting the data in storage is the primary purpose of the strong encryption requirements, but just as the PCI DSS applies to anyone who stores, processes, or transmits CHD, the same principles of strong encryption apply to all communication to and from the cardholder data Environment (CDE).
In our experiences working with companies that are trying to comply with the PCI DSS, we have seen several common errors when it comes to implementation of encryption, all of which can (and should) be avoided.
“We haven’t looked at the encryption code lately, but it seems to work, so we leave it alone.”
A given cryptographic algorithm doesn’t change over time, but its practical strength does, as advances in computational power and/or weaknesses discovered by cryptanalysts render old algorithms less effective. For this reason, you need to review older encryption and hashing code and upgrade the algorithms used. This can create complexity for existing encrypted data, so careful consideration needs to be put into the migration strategy.
“I store the key in N pieces and reconstruct it in-memory; no one will find it.”
This is a tricky one; the PCI DSS does allow for fragmenting the key into “at least two full-length key components or key shares, in accordance with an industry-accepted method”; however, simply implementing code to piece together the key from “random” variables or using misdirection in code to obfuscate the key construction isn’t generally considered an “industry-accepted method.” There are several forms of secret sharing that could be considered appropriate, but in general, you are better off leveraging operating-system tools such as DPAPI in Windows, a hardware security module (HSM), or a virtual equivalent such as Azure Key Vault or AWS Key Management Server. By doing this, you can separate the Data Encryption Key from the mechanism used to secure that key (e.g. a Key Encryption Key), which can satisfy the intent of the requirements.
“I wrote the algorithm/protocol myself, so I know it is secure.”
It always pains me to have to tell people that it is exceedingly unlikely that they wrote a better algorithm or protocol than AES or RSA. Writing strong encryption is hard, and even the experts make mistakes, which is which is why algorithms like DES, RC4, and MD5 are no longer considered sufficiently secure and need to be upgraded. The PCI DSS specifically requires that “strong” cryptography be used, which is extremely difficult to prove for custom algorithms and, in any case, entirely impractical, so you are much better off using proven public algorithms. Don’t reinvent the wheel.
The PCI DSS doesn’t tell you which cryptographic algorithms to use in most cases, instead referring to industry standard such as NIST, which change over time. Therefore, your use of cryptography must be reviewed periodically to ensure that the current implementation meets the requirements. The time to perform these reviews is not when you are preparing for your next attestation – upgrading cryptography takes planning and effort to ensure a smooth transition, so get in the habit of reviewing your application’s use of cryptography at least every six months, if not every quarter. You should also perform thorough reviews of all new code that leverages cryptography even in a trivial way to ensure that it’s being done in accordance with the requirements of PCI DSS. Above all, use standard, well-reviewed, strong algorithms and tools/systems that are known to be PCI DSS-validated.