Recently I received an interface specification of a security related product. It sensibly did not use its own encryption format. As most of the interface was XML, it decided to employ XML encryption to provide confidentiality of the data. They decided to fully keep within the standard - they even added restrictions on the format of the standard. Instead of ISO 10126 padding they decided to use PKCS#5 padding. The difference is tiny: ISO 10126 padding is basically RR RR RR 04 (in hexadecimals, of course) where RR is a random number and PKCS#5 padding is 04 04 04 04 if you need to pad 4 bytes. Please just keep this in mind for now.
Processing of invalid decrypted data if an integrity checking mechanism is not used in conjunction with encryption. {List: Lambert, FTF1}That's nice but it is not enough of a warning. Actually, in the XML encryption standard you will find that they opt in their examples for signatures before encryption.
After that small intermezzo, we return to the padding and a attack called a padding oracle attack. To successfully perform a padding oracle attack, you need just two things:
- an oracle that tells you if your plain text is correctly padded, i.e. if decryption succeeded or not
- an encryption scheme that uses CBC encryption and a known padding
How bad is this? Well, without going into details: you need 128 tries on average to reveal one byte of plain text, regardless of the block cipher used. So if you have 1K of cipher data, you need 128K attacks to retrieve all plain text data. That's pretty serious - basically all your plain text data is available to anyone that can apply this attack. It took me all of four hours to implement a padding oracle demonstration. It will take me another day at most to implement it for the specific service (performing the base64 encoding, wrapping the base64 encoded data in XML and implement the HTTP client).
So if you own a service: make sure your data is integrity checked before doing any decryption. If that is not possible: don't give more information to any attacker than absolutely necessary (e.g. use ISO 10126 over PKCS#5, and make sure timing attacks are not possible). Even better: use TLS to protect your data in transit; only use XML encryption if you want to keep your data safe on the server after reception. Finally: always keep to the standards and use the defaults if you are unsure.
Hopefully the next XML encryption standard will default to an encryption scheme that does provide an integrity check (e.g. a MAC).