一对建议:
16个字符的ASCII字符串是128^16 = 5.19229686e33
可能的键输入.Base64编码16个字节产生24个字节(4*ceil(16/3)
).因此,即使您使用的是192位AES密钥(理论上是6.27710174e57
密钥组合),您也只能使用1/1208925820422879877545683
[超过一万亿亿].实际上,您将密钥大小设置为256位,显然代码忽略了/允许192位密钥没有错误.
使用Rfc2898DeriveBytes
导出您的AES密钥,而不是原始字符串的Base64编码转换.RFC 2898定义了PBKDF2(基于密码的密钥派生函数2),一种基于HMAC的密钥派生函数,用于从密码中安全地派生加密密钥,并提供使用大量迭代的HMAC/SHA1,以减轻对您的暴力攻击键.
您只TransformFinalBlock()
在PowerShell中调用加密和解密.我想如果消息长于一个块(16个字节),这将无法加密或解密完整的消息.尝试使用输入消息,如This is a plaintext message.
(29个字节).我相信你想要同时使用TransformBlock()
和TransformFinalBlock()
.
你是正确的,静态IV是不安全的(违背了IV的目的,对于每个使用相同密钥的加密操作,它应该是唯一的且不可预测的).AesManaged
已经提供了一种GenerateIV()
生成令人满意的IV 的方法,您可以从IV属性访问并添加到密文.
Base64编码的密文文本的PowerShell输出为44个字符(16 byte IV + 16 byte ciphered message = 32 bytes -> 44 bytes
在Base64中).您的Python Base64输出是24个字符(16 bytes -> 24 bytes
在Base64中).此输出不包括IV或消息(或输出有限的其他一些不太可能的原因).查看代码,您的encrypt
方法不会将IV添加到密文上.
最后,在这一点上,您的代码应该工作并且内部一致且交叉兼容.在这里,您应该重新审视几个设计决策:
零填充是非标准的,虽然您已手动实现,但是PKCS #5/#7
更加需要一个明确定义的填充方案.在Python和.NET中都有丰富的实现和代码示例.
您正在使用CBC分组密码操作模式.虽然CBC对保密性很好,但它不能提供完整性.您应该使用经过身份验证的加密模式(AE/AEAD),如GCM或EAX.如果不能,请使用HMAC/SHA-256等HMAC/SHA-256等加密密钥提供不同的共享密钥,在密文上提供消息验证码(MAC),并在尝试解密之前使用固定时间方法验证MAC .