AES Python加密和Ruby加密 - 不同的行为? [英] AES Python encryption and Ruby encryption - different behaviour?

查看:205
本文介绍了AES Python加密和Ruby加密 - 不同的行为?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这个网站,我有这个代码段:

From this site I have this code snippet:

>>> from Crypto.Cipher import AES
>>> obj = AES.new('This is a key123', AES.MODE_CBC, 'This is an IV456')
>>> message = "The answer is no"
>>> ciphertext = obj.encrypt(message)
>>> list(bytearray(ciphertext))
[214, 131, 141, 100, 33, 86, 84, 146, 170, 96, 65, 5, 224, 155, 139, 241]

当我使用这个数组并将其转换成Ruby中的String并继续解密时,会发生错误:

When I take this array and turn it into a String in Ruby and proceed to decrypt it, an error occurs:

>> require 'openssl'
=> true
>> obj2 = OpenSSL::Cipher::Cipher.new("AES-128-CBC")
=> #<OpenSSL::Cipher::Cipher:0x007fa388389b30>
>> obj2.decrypt
=> #<OpenSSL::Cipher::Cipher:0x007fa388389b30>
>> obj2.key = 'This is a key123'
=> "This is a key123"
>> obj2.iv = 'This is an IV456'
=> "This is an IV456"
>> ciphertext = [214, 131, 141, 100, 33, 86, 84, 146, 170, 96, 65, 5, 224, 155, 139, 241].pack('c*')
=> "\xD6\x83\x8Dd!VT\x92\xAA`A\x05\xE0\x9B\x8B\xF1"
>> obj2.update(ciphertext) + obj2.final
OpenSSL::Cipher::CipherError: bad decrypt
    from (irb):20:in `final'
    from (irb):20
    from /home/danyel/.rbenv/versions/2.0.0-p0/bin/irb:12:in `<main>'

为什么这不起作用?

推荐答案

这是可以理解的混乱 - PyCrypto在这里走了一些铁轨,破坏了通常的实现。如果您熟悉加密数据通常是什么样子,则Python输出看起来显然是错误的,并给您一个开始的地方。如果你不是,很容易想知道出了什么问题,不知道从哪里开始。

This is understandably confusing—PyCrypto has gone a bit off the rails here and broken with the usual implementation. If you're familiar enough with what encrypted data should normally look like, the Python output looks blatantly wrong and gives you a place to start. If you're not, it's easy to wonder what the heck went wrong and have no idea where to start looking.

在正常实现中,将使用填充默认情况下,您最终将使用16字节更长的加密输出。

In a "normal" implementation, padding will be used by default and you'll end up (in this case) with encrypted output that's 16 bytes longer.

加密使用Ruby,例如,这是结果: p>

Encrypted using Ruby, for example, this is the result:

>> ciphertext
=> "\xD6\x83\x8Dd!VT\x92\xAA`A\x05\xE0\x9B\x8B\xF1\xD5f\xC7\xFFNI\xC7N\xBC-;!\f\xF1!\xB4"
>> ciphertext.bytes
=> [214, 131, 141, 100, 33, 86, 84, 146, 170, 96, 65, 5, 224, 155, 139, 241, 213, 102, 199, 255, 78, 73, 199, 78, 188, 45, 59, 33, 12, 241, 33, 180]

PyCrypto,立即找到,已经选择只能使用未附加的数据。当与PyCrypto交换数据时,您将需要适当配置任何其他库。

PyCrypto, for reasons I cannot immediately find, has chosen to work only with unpadded data. When interchanging data with PyCrypto, you'll want to configure any other libraries appropriately.

对于Ruby的OpenSSL库, Cipher 对象公开一个可用于禁用填充的 padding 属性:

In the case of Ruby's OpenSSL library, the Cipher object exposes a padding property which can be used to disable padding:

>> require 'openssl'
=> true
>> obj2 = OpenSSL::Cipher::Cipher.new("AES-128-CBC")
=> #<OpenSSL::Cipher::Cipher:0x007fe62407a9b0>
>> obj2.decrypt
=> #<OpenSSL::Cipher::Cipher:0x007fe62407a9b0>
>> obj2.key = 'This is a key123'
=> "This is a key123"
>> obj2.iv = 'This is an IV456'
=> "This is an IV456"
>> obj2.padding = 0
=> 0
>> ciphertext = [214, 131, 141, 100, 33, 86, 84, 146, 170, 96, 65, 5, 224, 155, 139, 241].pack('c*')
=> "\xD6\x83\x8Dd!VT\x92\xAA`A\x05\xE0\x9B\x8B\xF1"
>> obj2.update(ciphertext) + obj2.final
=> "The answer is no"

这篇关于AES Python加密和Ruby加密 - 不同的行为?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆