I need to encrypt something on my server and save the result. Since I am not a security expert, I want to implement as much existing code as possible.

I found a fully build function on php.net but it says that "is not protected against padding oracle attacks."

What are "padding oracle attacks" and what should I do about it?


The padding oracle is a mixture of a protocol flaw and an implementation flaw. Namely, a "padding oracle" leaks some information about secret data through how it reacts to maliciously crafted invalid input. A good protocol will first validate the input data through a MAC before considering decryption and its corollary, padding processing. That's what the "encrypt-then-MAC" construction is about. A bad protocol will do things in the wrong order, and may suffer from leakage by applying decryption first; that's what happens in SSL with CBC encryption modes.

If the protocol is bad, then the implementation must be specially shielded against the kind of invalid messages that attackers will try to handcraft in order to turn some implementation (e.g. a server) into a padding oracle. Such shielding is hard (e.g. the Lucky Thirteen attack demonstrates, in lab conditions, the theoretical possibility of leakage even with thoroughly shielded implementations).

The PHP function you link too is only about encryption; by definition, it cannot do anything against padding oracles. Protection against padding oracles is more at the protocol level. As is typical with PHP, dangerous functionality is provided with little warning, and a suboptimal API.

Designing your own secure protocol is even harder than shielding against side-channel attacks, so don't do that. And even if you do, don't do that in PHP.

  • 1
    +1 for excellent succinct answer and allusions to Schneier's law and "If you are typing A E S..." which I've been linking a lot of people to this week. – adric Jul 16 '13 at 17:13

To protect against padding oracles, you want to make sure that your application does not return a different error when the padding is wrong. The best way to do this is an Encrypt-then-MAC construction, where a Message Authentication Code (MAC) is applied to the ciphertext. If the MAC fails, you don't even need to look at the padding. If the MAC is correct, it is cryptographically unlikely that the padding has been tampered with.

  • 3
    +1 As an aside it should be noted, that taking different amounts of processing time is in effect returning a different error. The user can time their requests and use that as their oracle (if say the relatively slow decryption is only done if the padding is kosher). Granted Encrypt-then-MAC will satisfy this property, since as you said the validity of the padding won't get checked with an invalid MAC. – dr jimbob Jul 16 '13 at 15:42

Just to say it my way, first, an "oracle" in cryptography is based on the concept of a mythological oracle; a person with a direct line to a deity, and thus with access to information that mere mortals do not have. In cryptography, oracles are "black boxes" that can perform tasks that would be difficult for the attacker, and can thus give an attacker information that is normally difficult to obtain.

A padding oracle, specifically, can tell the attacker whether a message he inputs into it is properly padded (most block cipher modes use some form of removable data padding to ensure that the message length is an exact multiple of the cipher's block size). It does this by attempting to decrypt the message, and behaving differently when a block is or is not padded correctly, such behavior differences being visible to the attacker. The padding oracle is usually an unwitting participant; the attacker typically hijacks an initialized cipher implementation, feeding it specially-crafted messages of his choosing in what's known as a chosen-ciphertext attack.

A related type of attack is a timing attack; it's one way that a decryption implementation can be turned into a padding oracle, by measuring the time it takes to determine whether the block is properly padded. Some cipher modes, like CBC, can be decrypted in any order, and so some implementations will decrypt the last block first to check the padding of the message, in an attempt to "fail fast" on corrupted messages. However, the difference between the time it takes to check the padding and to attempt to decrypt the full message can be used by an attacker to determine which of the two happened, even if the error shown to the attacker is the same in either case.

To guard against these types of attacks, there must be no discernible difference in behavior between an attempt to decrypt a message that is not properly padded compared to one that is. The best known way to do this is to incorporate a secure checksum known as a Message Authentication Code. This MAC is typically produced by a secure "keyed hash", using the same key that encrypted the message. The message is first encrypted, and then the ciphertext, along with information about how it was encrypted such as the cipher algorithm, cipher mode, key size, block size and IV, is hashed using the MAC algorithm and the same key.

To decrypt, the algorithm first recomputes the MAC given the ciphertext and ciphering information shared between the two computers. If the computed MAC does not match the one included with the ciphertext, decryption fails; either the message, MAC or both have been changed in transit by some means, either benign (data corruption) or malevolent (attempted attack).

The chances of an attacker, not knowing the key, being able to change the ciphertext and its MAC in a consistent way is believed to be difficult, and by that I mean a roughly 1 in 2^(keysize) chance, so the strategy of systematically changing the message becomes less efficient than simply trying every possible key. In addition, because the same operation, which pretty much always takes the same time, can detect any post-encryption data issue that would make the message invalid, an attacker can't tell the difference made by any systematic change to the ciphertext and MAC; it either matches (extremely unlikely; see above) or it doesn't (much more likely).

  • In software testing an oracle is how you know if a test passed or failed. The plaintext padding discovered in this attack seems to fit nicely to that simpler definition :) Ref: BBST – adric Jul 16 '13 at 17:09
  • Well, oracles don't just give pass/fail results. The "random oracle" is another useful conceptual oracle, which takes in messages and produces random numbers that are always the same for a given message but never the same for any two different messages. This is the conceptual idea that we simulate with hash functions. We don't know how it's done (in fact we cannot achieve such behavior computationally) and don't need to know; all we have to know is how to use it. – KeithS Jul 16 '13 at 18:01
  • Oracles get their name from exactly what I describe. I tailored the cryptographic definition towards a malicious attack, but white hats and other good guys can use oracles just as effectively for benevolent purposes, including the intended purpose for a particular security scheme. – KeithS Jul 16 '13 at 18:02

The Padding Oracle Attack is a side channel attack that can be used to decrypt ECB or CBC symmetric ciphers. This attack works leakaging information about the padding during decryption of the ciphertext. To prevent this you can add authentication to the ciphertext, for instance using HMAC. The most used technique is Encrypt-then-MAC.

In PHP, you can use the Zend\Crypt\BlockCipher component of Zend Framework 2, that implements Encrypt-then-MAC using HMAC, providing a very simple API:

use Zend\Crypt\BlockCipher;

$blockCipher = BlockCipher::factory('mcrypt', array('algo' => 'aes'));
$blockCipher->setKey('encryption key');
$ciphertext = $blockCipher->encrypt('this is a secret message');
echo "Ciphertext: $ciphertext \n";
$plaintext = $blockCipher->decrypt($ciphertext);
echo "Plaintext: $plaintext \n";

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.