Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

AES-128 CBC increases number of bytes and doesn't decode correctly #95

Open
Wastus opened this issue Aug 5, 2020 · 4 comments
Open
Labels

Comments

@Wastus
Copy link

Wastus commented Aug 5, 2020

Steps to reproduce the bug

  1. Navigate to cryptii.com/pipes/aes-encryption.

  2. Select AES 128 CBC with the following parameters:
    key: 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F
    IV: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
    Input data:
    00 00 10 00 FF FF FF 00 00 2D 3F 7F 4E 03 A9 D1

  3. The output will be:
    47 5f dc 30 79 3b ae 85 55 0c 6e 5d 61 58 fb c7 4f 64 3a ae ca df 7a 50 5f 01 e0 29 bd 6d 50 4c

  4. Switch to decode and input only:
    47 5f dc 30 79 3b ae 85 55 0c 6e 5d 61 58 fb c7

  5. The decode will fail because of a wrong input

Describe what you expected to happen
The output of a complete block should be a block of equal size. So a 16 byte input block should result in a 16 byte output block.

The output should just be:
47 5f dc 30 79 3b ae 85 55 0c 6e 5d 61 58 fb c7

And decoding that block back should work as well.

Version, environment and state

Inside the web app press Ctrl+I, copy the presented alert text and paste it into the block below.
This isn't working for Vivaldi or Chrome - I can't find a way to copy the data from the alert box which appears. Here is a workaround: stackexchange

{"version":"4.0.8+dev.1646d05","env":{"name":"chrome","version":"84.0.4147","os":"Windows 10","type":"browser"},"pipe":{"id":2788481236,"url":"https://cryptii.com/pipes/aes-encryption","title":"AES Encryption: Encrypt and decrypt online","description":"The Advanced Encryption Standard (AES), also known by its original name Rijndael is a specification for the encryption of electronic data. It describes a symmetric-key algorithm using the same key for both encrypting and decrypting.","items":[{"name":"bytes","settings":{"format":"hexadecimal","groupBits":8}},{"name":"block-cipher","settings":{"algorithm":"aes-128","mode":"cbc","key":"AAECAwQFBgcICQoLDA0ODw==","iv":"AAAAAAAAAAAAAAAAAAAAAA=="}},{"name":"bytes","settings":{"format":"hexadecimal","groupBits":8}}],"content":{"data":"AAAQAP///wAALT9/TgOp0Q==","encoding":"base64"}}}
@Wastus Wastus added the bug label Aug 5, 2020
@cpegeo
Copy link

cpegeo commented Mar 9, 2021

I can confirm this issue. I have tested this with a 512 byte input for AES-128 CBC and when an encryption is performed it adds 16 bytes to the data.

image

Using other 3rd party encryption tools, this data is not appended and matches expected. When attempting to decrypt the 512 bytes of cyphertext from other tools, this tool fails. It is only able to decrypt if it has the extra 16 bytes padded.

Decrypting the cypher text with another tool shows that this tool is appending 16 instances of '0x10' to the end of the data.

@cpegeo
Copy link

cpegeo commented Mar 9, 2021

A little more info:

This issue seems to be related to padding. It appears that the encoding is set to use CMS padding which pads with the same value as the number of padding bytes (in my example above the value of 16).

What I am still unsure about is why padding is being added to an input that is evenly divisible by the block length (16 bytes).

@cpegeo
Copy link

cpegeo commented Mar 9, 2021

I've determined that this is not necessarily a bug. The algorithm used for encryption/decryption uses PKCS#7 padding.

per Wiki:

"If the length of the original data is an integer multiple of the block size B, then an extra block of bytes with value B is added. This is necessary so the deciphering algorithm can determine with certainty whether the last byte of the last block is a pad byte indicating the number of padding bytes added or part of the plaintext message. Consider a plaintext message that is an integer multiple of B bytes with the last byte of plaintext being 01. With no additional information, the deciphering algorithm will not be able to determine whether the last byte is a plaintext byte or a pad byte. However, by adding B bytes each of value B after the 01 plaintext byte, the deciphering algorithm can always treat the last byte as a pad byte and strip the appropriate number of pad bytes off the end of the ciphertext; said number of bytes to be stripped based on the value of the last byte."

My recommendation is to add language to the interface to indicate that the algorithm used is "AES-CBC with PKCS#7 Padding". Additionally it would be nice to add a feature to enable/disable padding for Enc/Dec.

@Wastus
Copy link
Author

Wastus commented Mar 12, 2021

Thanks for your analysis, I haven't come across an implementation which uses PKCS#7 padding and didn't knew that it even existed - that's why I filed this bug.

While I still think that most implementations do not use PKCS#7 padding, having it at least mentioned would help to identify the root cause for the unexpected behavior. I'll leave this open for the documentation and support your feature request to enable and disable this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants