【问题标题】:Why doesn't it work when using Python to encrypt, then Ruby to decrypt?为什么使用 Python 加密,然后使用 Ruby 解密时不起作用?
【发布时间】:2013-07-31 01:47:50
【问题描述】:

我试图encrypt 然后base64_encode 使用Python 的字符串,然后base64_decode 然后decrypt 使用Ruby 的结果,但字符串搞砸了。

我看不出这两种方法有什么不同。我尝试使用 128 位 AES-CFB 算法,但没有成功。

这是我的 Python 代码:

from Crypto.Cipher import AES
from Crypto.Util.randpool import RandomPool
from base64 import standard_b64encode, standard_b64decode

key = "abcdefghijklmnop"
en = AES.new(key, AES.MODE_CFB, "0000000000000000")
cipher = en.encrypt("apple")
cipher64 = standard_b64encode(cipher)

cipher64 包含:WqF9Zj0=

我的 Ruby 代码是:

require "openssl"
require 'digest/sha2'
require 'base64'


de = OpenSSL::Cipher::Cipher.new("aes-128-cfb")
de.decrypt
de.key = "abcdefghijklmnop"
de.iv = "0000000000000000"
plain = de.update("WqF9Zj0=".unpack('m')[0])
de.final
puts plain

plain 包含与"apple" 不同的字符串。如果我的字符串长度为 16,我会得到相同的结果,以避免填充问题。

我猜这是一个参数问题,但我不知道是什么。有人有想法吗?

【问题讨论】:

    标签: python ruby encryption


    【解决方案1】:

    PyCrypto 使用不同的segment_size

    编码时,指定segment_size,并填充纯文本。

    from base64 import standard_b64encode
    
    from Crypto.Cipher import AES
    
    def pad(x, n=16):
        p = n - (len(x) % n)
        return x + chr(p) * p
    
    key = "abcdefghijklmnop"
    en = AES.new(key=key, mode=AES.MODE_CFB, IV="0" * 16, segment_size=128)
    cipher = en.encrypt(pad("apple"))
    cipher64 = standard_b64encode(cipher)
    print cipher64
    

    使用上面的代码,你会得到apple\x03\x03\x03。在 Ruby 方面,您应该删除填充。

    Ruby 部分(解码):

    require "openssl"
    
    de = OpenSSL::Cipher::Cipher.new("aes-128-cfb")
    de.decrypt
    de.key = "abcdefghijklmnop"
    de.iv = "0000000000000000"
    plain = de.update(ARGV[0].unpack('m')[0]) + de.final
    plain = plain[0...-plain[-1].ord]
    puts plain
    

    或者,您可以使用 M2Crypto,它无需删除 Ruby 端的填充:

    from base64 import standard_b64encode
    
    import M2Crypto.EVP
    
    key = "abcdefghijklmnop"
    iv = "0000000000000000"
    en = M2Crypto.EVP.Cipher('aes_128_cfb', key, iv, 1)
    cipher = en.update('apple') + en.final()
    cipher64 = standard_b64encode(cipher)
    print cipher64
    

    【讨论】:

    • 谢谢,但如果输入的苹果字符串长于 8 个字符,我仍然会遇到问题。在 python 方面我已经:from Crypto.Cipher import AES en = AES.new(key, AES.MODE_CFB, "0000000000000000", segment_size = 64) cipher = en.encrypt(pad(sys.argv[1])) 和在 ruby​​ 方面我已经:require "openssl" decryptobj = OpenSSL::Cipher::Cipher.new("AES-256-CFB")。不幸的是,我无法访问 M2Crypto。
    • 啊,终于找到了解决方案:我需要通过编码和 16 字节长的填充来使用 segment_size = 128 :-)。
    • @user2194805,我解决了这个问题。我还添加了去除填充的 ruby​​ 代码。
    • 未来用户的注意事项 - 这个答案几乎让我绊倒了。段大小仅在 CFB 模式下是一个问题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-11-07
    • 1970-01-01
    • 2020-09-24
    • 1970-01-01
    • 2020-03-07
    • 2020-06-18
    • 1970-01-01
    相关资源
    最近更新 更多