简体   繁体   English

当纯文本字符数 > 16 时,C# 到 Python 密码文本不同

[英]C# to Python Cipher Text Differs When Plain Text Character Count > 16

I want to convert ac# code to python like this question: Python to C# AES CBC PKCS7我想像这个问题一样将 ac# 代码转换为 python: Python to C# AES CBC PKCS7

When plain text's character count < 16, I give the same result both of this codes.当纯文本的字符数 < 16 时,这两个代码的结果相同。 (24 character) (24 个字符)

But when plain text's character count >= 16, C# code returns result that has 44 characters and python returns result that has 24 characters.但是当纯文本的字符数 >= 16 时,C# 代码返回有 44 个字符的结果,python 返回有 24 个字符的结果。 This are same characters but python is missing.这是相同的字符,但缺少 python。 For example: c# result is jfgdohpE8zrgls3Mpi8B+t/nGbzK1iEA3l1rJ0G8sFU= , python result is jfgdohpE8zrgls3Mpi8B+g== Why?例如:c# 结果是jfgdohpE8zrgls3Mpi8B+t/nGbzK1iEA3l1rJ0G8sFU= ,python 结果是jfgdohpE8zrgls3Mpi8B+g==为什么? ( I use Python3 and PKCS7 library for padding) (我使用 Python3 和 PKCS7 库进行填充)

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.必须在 Python 代码中删除才能派生出与 C# 代码中相同的密钥。

Then the problem you describe can be reproduced: The C# code returns eg for the base64 encoded IV J223ULe3Xf6PX1KfNVmEiw== and the plaintext and key posted by you the following ciphertext:然后可以重现您描述的问题:C# 代码返回例如 base64 编码的 IV J223ULe3Xf6PX1KfNVmEiw==以及您发布的明文和密钥以下密文:

O5EBcIB987RNfZ41RbvRThmlEyP2RxkDCuGWQiajkDY=

while the Python code generates this ciphertext:而 Python 代码生成此密文:

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)).原因是pypkcs7问题 #1 )中的一个已知错误,这使得这个包实际上无法使用,因为填充通常不再符合 PKCS7 定义(特别是如果填充前的明文长度是块大小(AES 为 16 字节))。

So you need a different PKCS7 implementation.所以你需要一个不同的 PKCS7 实现。 Fortunately PyCryptodome provides a padding module (not available in legacy PyCrypto ).幸运的是PyCryptodome提供了一个填充模块(在旧版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).生成的密文与 C# 代码生成的密文相同(顺便说一下,实际上可以省略解码,因为加密过程再次对密文进行编码;我保留这个只是为了与旧实现进行比较)。

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"

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM