【问题标题】:AES Python encryption and Ruby encryption - different behaviour?AES Python 加密和 Ruby 加密 - 不同的行为?
【发布时间】:2013-10-29 14:48:08
【问题描述】:

来自this 网站我有这个代码sn-p:

>>> 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 中的字符串并继续解密时,会发生错误:

>> 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>'

为什么这不起作用?

【问题讨论】:

    标签: python ruby encryption aes


    【解决方案1】:

    这是可以理解的混乱——PyCrypto 在这里有点偏离了轨道,并与通常的实现不同。如果您对加密数据通常应该是什么样子足够熟悉,那么 Python 输出 看起来 明显错误,并为您提供了一个开始的地方。如果你不是,很容易想知道到底出了什么问题,不知道从哪里开始。

    在“正常”实现中,默认情况下将使用填充,并且您最终(在这种情况下)将得到长 16 个字节的加密输出。

    例如使用 Ruby 加密,结果如下:

    >> 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,由于我无法立即找到的原因,选择了work only with unpadded data。与 PyCrypto 交换数据时,您需要适当地配置任何其他库。

    对于 Ruby 的 OpenSSL 库,Cipher 对象公开了一个可用于禁用填充的 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.MODE_CFB吗?
    • 我假设你没有。知道如何在不创建新问题的情况下公开(或提出)这个“问题”吗?
    • 你怎么能从 Ruby 转向 Python。 Python 似乎总是抱怨“ValueError:输入字符串的长度必须是 16 的倍数”
    • 对某些人来说,正向就是反向 :)
    猜你喜欢
    • 1970-01-01
    • 2018-11-28
    • 1970-01-01
    • 1970-01-01
    • 2014-04-30
    • 1970-01-01
    • 2016-06-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多