1

I want to convert a c# code to python like this question: Python to C# AES CBC PKCS7

When plain text's character count < 16, I give the same result both of this codes. (24 character)

But when plain text's character count >= 16, C# code returns result that has 44 characters and python returns result that has 24 characters. This are same characters but python is missing. For example: c# result is jfgdohpE8zrgls3Mpi8B+t/nGbzK1iEA3l1rJ0G8sFU=, python result is jfgdohpE8zrgls3Mpi8B+g== Why? ( I use Python3 and PKCS7 library for padding)

4
  • 1
    None of the two codes compile/run. The Python code lacks the definition for PKCS7Encoder. Also missing for both codes are complete samples to reproduce the problem (ciphertext without plaintext and key don't help much). Please post an MCVE. Commented Nov 24, 2020 at 13:26
  • Can u look at it now? I made some edits. @Topaco Commented Nov 24, 2020 at 14:22
  • The C# code still doesn't compile (array is not defined). Currently you are using a 32 byte key with 0 values (array_bbb). array_bbb_2 is not used at all. No idea what you want to achieve. Commented Nov 24, 2020 at 14:27
  • During the first copy operation you copy the bytes 0-15 (array_bbb_2) to 0-15 (array_bbb). In the second copy operation you copy 0-15 (array_bbb_2) to 15-30 (array_bbb). Thereby the last byte of the first copy operation is overwritten. Is this really how it should be? Commented Nov 24, 2020 at 14:56

1 Answer 1

2

First of all, the line

AES_KEY = bytearray(bbb, 'utf-8') 

must be removed in the Python code to derive the same key as in the C# code.

Then the problem you describe can be reproduced: The C# code returns e.g. for the base64 encoded IV J223ULe3Xf6PX1KfNVmEiw== and the plaintext and key posted by you the following ciphertext:

O5EBcIB987RNfZ41RbvRThmlEyP2RxkDCuGWQiajkDY=

while the Python code generates this ciphertext:

O5EBcIB987RNfZ41RbvRTg==

The reason is an already known bug in pypkcs7 (issue #1) which makes this package practically unusable, because the padding generally does not comply with the PKCS7 definition anymore (specifically if the plaintext before padding has a length that is an integer multiple of the block size (16 bytes for AES)).

So you need a different PKCS7 implementation. Fortunately PyCryptodome provides a padding module (not available in legacy PyCrypto). With the following change

#from pkcs7 import PKCS7Encoder
from Crypto.Util.Padding import pad
...
#encoder = PKCS7Encoder()
#padded_text = encoder.encode(secret_text)    
padded_text = pad(secret_text.encode('utf8'), 16).decode('utf8')  

the same ciphertext is generated as by the C# code (by the way, the decoding can actually be omitted, because the encryption process encodes the ciphertext again; I have kept this only with regard to a comparison with the old implementation).

As a side note, the key can be more easily derived with:

hash = hashlib.sha256(bbb.encode('utf8')).digest() 
AES_KEY = hash[:15] + hash[:16] + b"\0"
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.