Padding oracle attack
View on WikipediaIn cryptography, a padding oracle attack is an attack which uses the padding validation of a cryptographic message to decrypt the ciphertext. In cryptography, variable-length plaintext messages often have to be padded (expanded) to be compatible with the underlying cryptographic primitive. The attack relies on having a "padding oracle" which freely responds to queries about whether a message is correctly padded or not. The information could be directly given, or leaked through a side-channel.
The earliest well-known attack that uses a padding oracle is Bleichenbacher's attack of 1998, which attacks RSA with PKCS #1 v1.5 padding.[1] The term "padding oracle" appeared in literature in 2002,[2] after Serge Vaudenay's attack on the CBC mode decryption used within symmetric block ciphers.[3] Variants of both attacks continue to find success more than one decade after their original publication.[1][4][5]
Asymmetric cryptography
[edit]In 1998, Daniel Bleichenbacher published a seminal paper on what became known as Bleichenbacher's attack (also known as "million message attack"). The attack uses a padding oracle against RSA with PKCS #1 v1.5 padding, but it does not include the term. Later authors have classified his attack as a padding oracle attack.[1]
Manger (2001) reports an attack on the replacement for PKCS #1 v1.5 padding, PKCS #1 v2.0 "OAEP".[6]
Symmetric cryptography
[edit]In symmetric cryptography, the padding oracle attack can be applied to the CBC mode of operation. Leaked data on padding validity can allow attackers to decrypt (and sometimes encrypt) messages through the oracle using the oracle's key, without knowing the encryption key.
Compared to Bleichenbacher's attack on RSA with PKCS #1 v1.5, Vaudenay's attack on CBC is much more efficient.[1] Both attacks target crypto systems commonly used for the time: CBC is the original mode used in Secure Sockets Layer (SSL) and had continued to be supported in TLS.[4]
A number of mitigations have been performed to prevent the decryption software from acting as an oracle, but newer attacks based on timing have repeatedly revived this oracle. TLS 1.2 introduces a number of authenticated encryption with additional data modes that do not rely on CBC.[4]
Padding oracle attack on CBC encryption
[edit]The standard implementation of CBC decryption in block ciphers is to decrypt all ciphertext blocks, validate the padding, remove the PKCS7 padding, and return the message's plaintext. If the server returns an "invalid padding" error instead of a generic "decryption failed" error, the attacker can use the server as a padding oracle to decrypt (and sometimes encrypt) messages.
The mathematical formula for CBC decryption is
As depicted above, CBC decryption XORs each plaintext block with the previous block. As a result, a single-byte modification in block will make a corresponding change to a single byte in .
Suppose the attacker has two ciphertext blocks and wants to decrypt the second block to get plaintext . The attacker changes the last byte of (creating ) and sends to the server. The server then returns whether or not the padding of the last decrypted block () is correct (a valid PKCS#7 padding). If the padding is correct, the attacker now knows that the last byte of is , the last two bytes are 0x02, the last three bytes are 0x03, …, or the last eight bytes are 0x08. The attacker can modify the second-last byte (flip any bit) to ensure that the last byte is 0x01. (Alternatively, the attacker can flip earlier bytes and binary search for the position to identify the padding. For example, if modifying the third-last byte is correct, but modifying the second-last byte is incorrect, then the last two bytes are known to be 0x02, allowing both of them to be decrypted.) Therefore, the last byte of equals . If the padding is incorrect, the attacker can change the last byte of to the next possible value. At most, the attacker will need to make 256 attempts to find the last byte of , 255 attempts for every possible byte (256 possible, minus one by pigeonhole principle), plus one additional attempt to eliminate an ambiguous padding.[7]
After determining the last byte of , the attacker can use the same technique to obtain the second-to-last byte of . The attacker sets the last byte of to by setting the last byte of to . The attacker then uses the same approach described above, this time modifying the second-to-last byte until the padding is correct (0x02, 0x02).
If a block consists of 128 bits (AES, for example), which is 16 bytes, the attacker will obtain plaintext in no more than 256⋅16 = 4096 attempts. This is significantly faster than the attempts required to bruteforce a 128-bit key.
Encrypting messages with Padding oracle attack (CBC-R)
[edit]CBC-R[8] turns a decryption oracle into an encryption oracle, and is primarily demonstrated against padding oracles.
Using padding oracle attack CBC-R can craft an initialization vector and ciphertext block for any plaintext:
- decrypt any ciphertext Pi = PODecrypt( Ci ) ⊕ Ci−1,
- select previous cipherblock Cx−1 freely,
- produce valid ciphertext/plaintext pair Cx-1 = Px ⊕ PODecrypt( Ci ).
To generate a ciphertext that is N blocks long, attacker must perform N numbers of padding oracle attacks. These attacks are chained together so that proper plaintext is constructed in reverse order, from end of message (CN) to beginning message (C0, IV). In each step, padding oracle attack is used to construct the IV to the previous chosen ciphertext.
The CBC-R attack will not work against an encryption scheme that authenticates ciphertext (using a message authentication code or similar) before decrypting.
Attacks using padding oracles
[edit]The original attack against CBC was published in 2002 by Serge Vaudenay.[3] Concrete instantiations of the attack were later realised against SSL[9] and IPSec.[10][11] It was also applied to several web frameworks, including JavaServer Faces, Ruby on Rails[12] and ASP.NET[13][14][15] as well as other software, such as the Steam gaming client.[16] In 2012 it was shown to be effective against PKCS 11 cryptographic tokens.[1]
While these earlier attacks were fixed by most TLS implementors following its public announcement, a new variant, the Lucky Thirteen attack, published in 2013, used a timing side-channel to re-open the vulnerability even in implementations that had previously been fixed. As of early 2014, the attack is no longer considered a threat in real-life operation, though it is still workable in theory (see signal-to-noise ratio) against a certain class of machines. As of 2015[update], the most active area of development for attacks upon cryptographic protocols used to secure Internet traffic are downgrade attack, such as Logjam[17] and Export RSA/FREAK[18] attacks, which trick clients into using less-secure cryptographic operations provided for compatibility with legacy clients when more secure ones are available. An attack called POODLE[19] (late 2014) combines both a downgrade attack (to SSL 3.0) with a padding oracle attack on the older, insecure protocol to enable compromise of the transmitted data. In May 2016 it has been revealed in CVE-2016-2107 that the fix against Lucky Thirteen in OpenSSL introduced another timing-based padding oracle.[20][21]
References
[edit]- ^ a b c d e Romain Bardou; Riccardo Focardi; Yusuke Kawamoto; Lorenzo Simionato; Graham Steel; Joe-Kai Tsay (2012). Efficient Padding Oracle Attacks on Cryptographic Hardware. Rr-7944 (report). INRIA. p. 19.
- ^ Black, John; Urtubia, Hector (2002). Side-Channel Attacks on Symmetric Encryption Schemes: The Case for Authenticated Encryption. USENET Security '02.
- ^ a b Serge Vaudenay (2002). Security Flaws Induced by CBC Padding Applications to SSL, IPSEC, WTLS... (PDF). EUROCRYPT 2002.
Similar attack model was used by Bleichenbacher against PKCS#1 v1.5 [5] and by Manger against PKCS#1 v2.0 [13]. This paper shows that similar attacks are feasible in the symmetric key world.
- ^ a b c Sullivan, Nick (12 February 2016). "Padding oracles and the decline of CBC-mode cipher suites". The Cloudflare Blog.
- ^ Hanno Böck; Juraj Somorovsky; Craig Young. "ROBOT attack: Return Of Bleichenbacher's Oracle Threat". Retrieved 27 February 2018.
- ^ Manger, James (2001). "A Chosen Ciphertext Attack on RSA Optimal Asymmetric Encryption Padding (OAEP) as Standardized in PKCS #1 v2.0" (PDF). Telstra Research Laboratories.
- ^ Is the padding oracle attack deterministic
- ^ Juliano Rizzo; Thai Duong (25 May 2010). Practical Padding Oracle Attacks (PDF). USENIX WOOT 2010.
- ^ Brice Canvel; Alain Hiltgen; Serge Vaudenay; Martin Vuagnoux (2003), Password Interception in a SSL/TLS Channel (PDF).
- ^ Jean Paul Degabriele; Kenneth G. Paterson (2007), Attacking the IPsec Standards in Encryption-only Configurations (PDF), archived from the original on 19 December 2018, retrieved 25 September 2018.
- ^ Jean Paul Degabriele; Kenneth G. Paterson (2010), On the (In)Security of IPsec in MAC-then-Encrypt Configurations, CiteSeerX 10.1.1.185.1534.
- ^ Juliano Rizzo; Thai Duong (25 May 2010). Practical Padding Oracle Attacks (PDF). USENIX WOOT 2010.
- ^ Thai Duong; Juliano Rizzo (2011). Cryptography in the Web: The Case of Cryptographic Design Flaws in ASP.NET (PDF). IEEE Symposium on Security and Privacy 2011.
- ^ Dennis Fisher (13 September 2010). "'Padding Oracle' Crypto Attack Affects Millions of ASP.NET Apps". Threat Post. Archived from the original on 13 October 2010.
- ^ Vlad Azarkhin (19 September 2010). ""Padding Oracle" ASP.NET Vulnerability Explanation". Archived from the original on 23 October 2010. Retrieved 11 October 2010.
- ^ "Breaking Steam Client Cryptography". Steam Database. Retrieved 1 May 2016.
- ^ Matthew Green; Nadia Heninger; Paul Zimmerman; et al. (2015), Imperfect Forward Secrecy: How Diffie–Hellman Fails in Practice (PDF). For further information see https://www.weakdh.org Archived 22 December 2019 at the Wayback Machine.
- ^ Matthew Green (3 March 2015). "Attack of the week: FREAK (or 'factoring the NSA for fun and profit')".; see https://www.freakattack.com Archived 5 March 2015 at the Wayback Machine for more information.
- ^ Matthew Green (14 October 2014). "Attack of the week: POODLE".; for further information, see https://www.poodle.io
- ^ OpenSSL Security Advisory [3rd May 2016], 3 May 2016
- ^ "Yet Another Padding Oracle in OpenSSL CBC Ciphersuites", The Cloudflare Blog, Cloudflare, 4 May 2016
Padding oracle attack
View on GrokipediaCryptographic Background
Block Ciphers and Operating Modes
A block cipher is a symmetric-key cryptographic algorithm that operates on fixed-size blocks of data, transforming an input block of a specific length into an output block of the same length using a secret key.[7] For example, the Advanced Encryption Standard (AES), a widely adopted block cipher, processes data in 128-bit blocks.[8] Block ciphers are typically used in modes of operation to handle messages longer than a single block or to provide additional security properties. One of the simplest modes is the Electronic Codebook (ECB) mode, where each plaintext block is encrypted independently to produce a corresponding ciphertext block, resulting in identical plaintext blocks yielding identical ciphertext blocks regardless of their position.[9] This property makes ECB vulnerable to pattern analysis, as repeated structures in the plaintext are preserved in the ciphertext, which is undesirable for most applications involving structured data.[10] To address these limitations, chained modes like Cipher Block Chaining (CBC) were developed, which introduce dependencies between blocks to obscure patterns. In CBC mode, each plaintext block is first exclusive-ORed (XORed) with the previous ciphertext block before encryption, ensuring that the resulting ciphertext depends on all preceding plaintext blocks.[9] For the first block, a randomly chosen initialization vector (IV) serves as the "previous ciphertext," which must be unpredictable to maintain security.[9] Mathematically, the encryption process for the -th block is represented as:Padding in Block Cipher Encryption
Block ciphers operate on fixed-size blocks of data, typically 64 or 128 bits, requiring the plaintext to be an exact multiple of the block length for encryption.[12] When the plaintext length does not align with this requirement, padding is added to extend it to the nearest block boundary, ensuring compatibility with the cipher's input constraints.[13] This process is essential in modes like CBC, where incomplete blocks would otherwise prevent proper encryption.[14] The most widely adopted padding scheme for block ciphers is PKCS#7, which generalizes PKCS#5 (originally defined for 8-byte blocks) to support arbitrary block sizes up to 255 bytes. In PKCS#7, if n bytes are needed to fill the block (where 1 ≤ n ≤ block size), n bytes each with the value n are appended to the plaintext.[15] For instance, a 10-byte message encrypted with a 16-byte block cipher (such as AES) would have 6 bytes of value 0x06 appended:Plaintext: [10 bytes of data] 06 06 06 06 06 06
This scheme ensures unambiguous removal during decryption by checking the value of the final byte to determine the padding length.[16] Other schemes, such as ANSI X.923, pad with n-1 zero bytes followed by a byte indicating n, while ISO 10126 uses random bytes for the first n-1 positions followed by the count n, though PKCS#7 remains the primary target in many implementations due to its prevalence.[17][18][19]
Upon decryption, the receiver verifies and removes the padding by examining the last byte to retrieve the padding length n, then confirms that the preceding n-1 bytes match the required value (e.g., all n in PKCS#7) before stripping them from the plaintext.[20] This validation step ensures the original message length is recovered accurately.[17] In practice, implementations often distinguish between padding-specific errors (e.g., invalid padding format) and general decryption failures (e.g., incorrect key), which can inadvertently expose side-channel information about padding validity.[21][22]
Core Attack Mechanism
Role of the Padding Oracle
A padding oracle refers to any component of a cryptographic system, such as a server or application, that distinguishes between decryption failures due to invalid padding and those caused by other errors, thereby leaking one bit of information per query about the correctness of the padding in the decrypted output.[23][24] This side-channel vulnerability arises when the system provides distinguishable feedback on padding validity, such as through error messages, response times, or exception handling.[23] In practical implementations, padding oracles often emerge in web services that return different HTTP status codes for padding-related errors versus other decryption issues—for instance, an HTTP 404 for invalid padding and a 500 for authentication or key errors.[24] Similarly, timing differences in server responses can serve as an oracle, where faster processing indicates invalid padding and slower processing signals valid padding after the check.[25] Exception types during decryption, such as Java'sBadPaddingException, can also leak this information by being exposed in error responses or logs.[2]
The term "padding oracle" and the underlying attack model were first formalized by Serge Vaudenay in his seminal 2002 paper "Security Flaws Induced by CBC Padding," presented at Eurocrypt, where he demonstrated vulnerabilities in protocols like SSL, IPSEC, and WTLS.[23]
Under the padding oracle model, an attacker interacts with the system by submitting tampered ciphertexts and observing binary responses—typically indicating whether the padding is valid following decryption—to iteratively infer details about the underlying plaintext.[23][26]
This mechanism enables efficient plaintext recovery, as each query yields one bit of feedback; in byte-oriented schemes like PKCS#7, recovering one byte of plaintext requires an average of 128 queries, with up to 256 trials in the worst case, allowing decryption of a full 128-bit block by sequentially recovering the full 8 bits of each of the 16 byte positions.[23]
Exploitation in CBC Mode
In the exploitation of a padding oracle attack within CBC mode, the attacker intercepts a ciphertext composed of chained blocks , where each plaintext block is computed as (with being the initialization vector). The goal is to recover an arbitrary target plaintext block by submitting modified ciphertexts to the oracle, which reveals whether the decrypted output has valid padding (e.g., PKCS#7, where the last bytes equal the value , for , and is the block size in bytes). The attacker can control modifications to the previous block while keeping fixed, leveraging the linear XOR operation in CBC decryption to directly influence bytes of . This setup enables a byte-at-a-time decryption process, starting from the end of the block to progressively ensure valid padding patterns.[1] The core process begins with the last byte () of , aiming to force a 1-byte padding (value ). The attacker modifies only the last byte of by XORing it with trial values (ranging from 0 to 255), such that the modified plaintext byte becomes . Each modified ciphertext is submitted to the oracle, which accepts if (valid for single-byte padding, as only the last byte is checked). The trial that yields acceptance satisfies , revealing . Equivalently, to test a specific guess for , the attacker sets the modified byte as ; oracle acceptance confirms the guess, since it forces . Up to 256 queries are required for this byte, with an expected 128 under uniform randomness.[1][2] For subsequent bytes (decreasing ), the process builds a longer valid padding prefix. For position , the padding length is , and the value is for all bytes from to . The attacker first fixes modifications for bytes to using previously recovered plaintext values: for each , set to ensure . Then, trial modifications are applied only to byte (trying all 256 values of , or equivalently testing guesses for via ), while keeping earlier bytes ( to ) unchanged. The oracle accepts precisely when (with later bytes already set to , satisfying the full -byte padding check). Thus, (or the tested ) is recovered upon acceptance. This step also requires up to 256 queries. The full block recovery repeats this for all positions, yielding the complete via final XOR with .[1][2] The attack's complexity is oracle queries per block in the worst case (exactly if exhaustively testing all guesses), or approximately on average, assuming uniform distribution over byte values. For a typical 128-bit block (), this equates to 2048–4096 queries, which is computationally feasible even under network latency constraints. This efficiency stems from the oracle's leakage enabling targeted byte recovery without key knowledge, exploiting CBC's malleability.[1][2]Attack Outcomes
Decrypting Arbitrary Ciphertext
The padding oracle attack enables the decryption of arbitrary ciphertext in CBC mode by exploiting the oracle's feedback on padding validity, allowing an attacker to recover plaintext blocks sequentially without knowledge of the encryption key. The process begins with the second block of the ciphertext, treating the preceding ciphertext block (or the initialization vector for the first block) as an effective "IV" that can be modified and submitted to the oracle. For each block, decryption proceeds byte-by-byte (or word-by-word, depending on the block cipher's granularity), starting from the least significant byte. The attacker crafts modified versions of the current block by altering bytes in the previous block (the effective IV), systematically testing values until the oracle indicates valid padding, from which the corresponding plaintext byte is deduced via XOR operations inherent to CBC decryption.[27] The initialization vector (IV) is handled as the zeroth ciphertext block, . If the IV is publicly known or fixed (as in many protocols), it serves directly as the starting point for decrypting the first plaintext block by modifying copies of . In scenarios where the IV is attacker-controllable, such as in certain network protocols, it can be directly manipulated to facilitate the attack; otherwise, the attack assumes the legitimate IV is available from the intercepted message. This sequential approach extends to subsequent blocks: once is recovered, the original becomes the effective IV for decrypting using modifications to , and so on for an -block message. The attack requires the system's malleability, meaning the attacker must be able to submit tampered ciphertexts to the oracle without detection or restriction beyond the padding check. Notably, it recovers only the plaintext, not the secret key, and thus breaks confidentiality but not necessarily the underlying cipher's strength.[27] As an illustrative example, consider a 32-byte ciphertext (two 16-byte blocks and , with a known 16-byte IV ) encrypted with a 128-bit block cipher like AES. To recover , the attacker generates modified versions of by altering bytes in , testing approximately 128 values per byte position on average (starting from the last byte to enforce PKCS#7 padding like ) across 16 bytes, requiring about 2,048 oracle queries. With known, decrypting uses the original as the effective IV and similarly modifies , adding another ~2,048 queries for a total of roughly 4,096—scalable linearly with message length. This aligns with practical implementations where query efficiency depends on the block size and alphabet (e.g., 256 possibilities per byte).[27] Serge Vaudenay formally proved in 2002 that the attack decrypts any CBC-padded message of blocks in expected time , where is the number of words per block and is the word size (e.g., for bytes), simplifying to for message length since constants like are fixed. For a typical 128-bit block (), this yields about 2,048 queries per block on average. The proof relies on the oracle providing one bit of information per query (valid/invalid padding), sufficient to resolve each byte via binary search-like trials. Limitations include dependency on consistent oracle responses without additional protections like message authentication, and vulnerability to "exploding" oracles that terminate sessions on invalid inputs, potentially increasing effective complexity.[27] For a practical demonstration, the following pseudocode outlines the core loop for decrypting a single block (of length words) using the padding oracle , assuming byte-level granularity for clarity (adaptable to words). It iteratively recovers the intermediate bytes, then XORs with the original effective IV to obtain the plaintext block :function decrypt_block(effective_IV, y, O):
p = array of size b, initialized to 0
dec_block = array of size b, initialized to 0
for i = b downto 1:
# Set padding for positions i to b: pad_val = b - i + 1
pad_val = b - i + 1
# Modify effective_IV[i] to guess dec_block[i], while setting later bytes to enforce padding
for guess = 0 to 255:
temp_IV = copy of effective_IV
temp_IV[i] = guess XOR pad_val # Trial value to make padding valid if guess matches dec_block[i]
for j = i+1 to b:
temp_IV[j] = dec_block[j] XOR (b - j + 1) # Enforce known padding bytes using recovered dec_block
modified_ciphertext = temp_IV + y # Full tampered input: modified previous + original current block (simplified for single block)
if O(modified_ciphertext) == VALID:
dec_block[i] = guess
break
if no guess found: # Rare, due to oracle properties
error
# Recover plaintext by XOR with original effective IV
for i = 1 to b:
p[i] = dec_block[i] XOR effective_IV[i]
return p # Full plaintext block
This loop averages 128 iterations per position, leveraging the CBC equation implicitly through oracle feedback.[27]