首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在Python3中正确处理AES.encrypt包含控制字符

如何在Python3中正确处理AES.encrypt包含控制字符
EN

Stack Overflow用户
提问于 2020-10-19 16:08:08
回答 1查看 42关注 0票数 1

我将把加密逻辑从php改为python3。

原始代码具有填充ascii的逻辑,我将其引入到我的python代码中。

从…

代码语言:javascript
复制
function toPkcs7 ($value)
{
    $padSize = 16 - (strlen ($value) % 16) ;
    return $value . str_repeat (chr ($padSize), $padSize) ;
}

代码语言:javascript
复制
def to_pkcs7(s):
    padding_size = 16 - (len(s) % 16)
    return s + (chr(padding_size) * padding_size)

但当to_pkcs7得到11个字符(例如"12345678901")和返回结果包含控制字符(例如12345678901\x05\x05,chr(5)表示ENQ \x05)时,两个加密器的工作方式不同。

我认为在python3的AES中可能忽略了结果的控制性。因为php toPkcs7python3 to_pkcs7返回相同长度字符串。

例如

代码语言:javascript
复制
# in php
$message = toPkcs7($message);
echo strlen($message);  # 16
$encrypted = openssl_encrypt($message, 'AES-128-CBC', $key, OPENSSL_RAW_DATA, $iv);

# in python3
message = to_pkcs7(message) 
print(len(message))  # 16
cipher = AES.new(key, AES.MODE_CBC, iv())
encrypted = cipher.encrypt(message.encode("utf-8"))

我想知道如何让我的python代码像php一样工作。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-10-19 17:21:02

在发布的PHP代码中,填充被做了两次,这是不必要的(实际上甚至是一个bug)。

填充的目的是明文的长度是块大小的整数倍(AES为16字节),这是块密码的要求。这已经通过第一填充实现,即第二填充是无用的。它只会导致附加了(这里) 0x10值的(冗余)完整块,这不必要地膨胀了密文。

为了获得具有Python代码的双填充明文的密文,还需要简单的双填充:

代码语言:javascript
复制
message = to_pkcs7(to_pkcs7(message)) 

要在PHP代码中只填充一次,请注意以下几点:openssl_encrypt()隐式使用PKCS7填充,即不需要自定义填充,因此只需删除即可。但是,如果应该应用自定义填充,则必须禁用隐式填充(通过设置OPENSSL_ZERO_PADDING标志)。这两种变体提供了相同的结果。

顺便说一句,PyCryptodome (不像传统的PyCrypto)在专用的module中支持PKCS7。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/64423423

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档