2.5 Cryptographic Attacks
Cryptographers classify attacks against cryptosystems into several categories. These attacks attempt to either retrieve the key or expose the plaintext. The algorithms discussed in this book are strong and resist all the attacks discussed here. However, the demands of a practical cryptosystem can easily introduce vulnerabilities even though the algorithm itself is strong. Much of the design presented in this book is aimed at mitigating these weaknesses.
A known-ciphertext attack is what most people think of as a cryptographic attack. The attacker has access only to the ciphertexts produced with a given key. These attacks can target either the key or the plaintext. Generally, we’ll assume that the attacker has all the ciphertexts.
In the case of a database, this is tantamount to the attacker’s having access to the database. Perhaps the attacker has found a weakness in the operating system that allows the database file itself to be downloaded, or perhaps a SQL injection attack is exposing the encrypted data. A properly placed insider often has easy access to all the data.
When the attacker has access to both the plaintext and the ciphertext, the attacker can mount a known-plaintext attack. People new to cryptography often dismiss known-plaintext attacks as a sort of "cheating." After all, if the attacker already has all the plaintexts, all the secrets have been exposed. We generally assume, though, that only some of the plaintext-ciphertext pairs are known. Perhaps all the past plaintexts prior to a certain date were compromised. The goal of a known-plaintext can be to recover the key or to uncover plaintext.
In a database context, it is often not too hard to find known plaintexts. The system might temporarily cache the plaintext prior to encryption, or the system might store the data unencrypted elsewhere in the system. This last case is far more common than you might think. For instance, say customer data is stored encrypted, but the data is decrypted in order to e-mail the invoice. The invoice might very well be stored in the database as well. If the invoice isn’t also encrypted, the attacker has a source of plaintexts to match with ciphertexts.
An even more subtle example is when data taken together must be encrypted but when the data is separate, it can be unencrypted. For instance, a customer’s name and credit card number might be encrypted when they are together in the order table. But another table, in the call tracking system, perhaps, might have the customer’s name unencrypted. If these two tables can be linked in a series of joins, the attacker has access to the plaintext. Database normalization can help security in this case, but in practice many databases are not highly normalized, so leaks like this are common.
As its name implies, a chosen-plaintext attacker can construct plaintext for the system to encrypt. This is a much more powerful version of a known-plaintext attack. An even more powerful variation is when the attacker can experiment by constructing new plaintexts based on the results of previously constructed plaintexts.
This attack is generally quite easy to mount against a database. In the case of an online ordering system, the attacker simply places additional orders with whatever data he would like to see encrypted. If he would like to see the ciphertext for "Kenan," placing a false order with that information would be suffucient. Unless the cryptosystem is designed carefully, the attacker would then be able to identify all the rows in the table with an order for "Kenan" (and encrypted with a particular key) by searching for the ciphertext produced by the chosen-plaintext attack.
2.5.1 Indirect Access of Keys
The general strategy to protect against direct access of keys is to design the cryptosystem to ensure that the keys are never available outside the code that uses them. Ideally, the keys are locked in dedicated tamper-proof hardware that also contains the cryptographic code. Indirect access, though, as discussed earlier, is a much thornier problem since programs must be able to decrypt the data in order to process it.4 If automatically launched programs can decrypt the data, a sufficiently motivated and skilled attacker will eventually be able to do the same.
In practice, an indirect access of keys is typically made through a function that passes data to the cryptosystem for decryption. This decryption function is often the weakest link in the security chain protecting encrypted data. If compromised, it will enable an attacker to decrypt arbitrary ciphertexts.5
Ideally, the cryptosystem is guarded by strong access controls that require authentication and authorization for each decryption call. To make this effective, though, the authorization check needs to occur as close to the actual decryption as possible. If a dedicated cryptographic device (discussed in Chapter 4, "Cryptographic Engines and Algorithms") is in use, the device should make the check itself. Unfortunately, that capability is very rare. The goal of these measures is to prevent the attacker from following the chain of function calls until a decryption call is found after the authorization check. If such a call is found, the attacker uses it for the decryption compromise attack.
Automated processes throw a wrinkle into this strategy. Automation, such as a batch credit card payment process, often needs access to decrypted data, and while it is certainly possible to require the automation to provide credentials prior to decrypting data, those credentials must also be stored and protected. The following discussion of data obfuscation covers this situation in more detail, but it is best to assume that if the attacker is sophisticated enough to break the application sufficiently to access the decryption function, he also will be capable of retrieving any credentials used by the automation.
Our approach is one of containment and observation. First, we ensure that the decryption function decrypts only the fewest necessary columns. This contains the damage in the case of a decryption compromise; the attacker won’t be able to decrypt all protected data in the system. Our next layer of defense, observation, is the critical control.
Extensive logging of decryption requests will expose sudden spikes caused by an attacker. Correlation of the logs with server processing and customer request logs helps reveal skimming.6 Honeycombing is also a valuable technique against an attempted decryption compromise.
Honeycombs are to applications and databases what honeypots are to networks. A honeycombed application has several APIs that are named and look like they should do what the attacker wants, but in reality they simply trigger alerts. A honeycombed database contains tables and views that look promising to potential attackers, but any select against them triggers an alert. In some cases, honeycombs can take the form of special rows in a table that look legitimate, but the data is fake and any query against them results in an alert. Any alert fired by a honeycomb is by definition suspicious since the honeycomb serves no actual business purpose and there is no reason in the normal course of business that the honeycomb would be accessed.