在Python中解密ruby DES-EDE3-CBC加密数据

问题描述 投票:0回答:1

我有一堆数据,通过以下代码在 Ruby 中加密

text = '12345678'
key = '6b4f0a29d4bba86add88be9d'
cipher = OpenSSL::Cipher.new('DES-EDE3-CBC').encrypt
cipher.key = key
s = cipher.update(text) + cipher.final
encrypted_text = s.unpack('H*')[0].upcase
# => 3B223AA60F1921F34CBBBAC209ACDCE4

可以在Ruby中解密

cipher = OpenSSL::Cipher.new('DES-EDE3-CBC').decrypt
cipher.key = key
s = [encrypted_text].pack("H*").unpack("C*").pack("c*")
cipher.update(s) + cipher.final
# => 12345678

现在我必须用 Python 解密数据。 我写的加密代码如下:

from Crypto.Cipher import DES3
from Crypto import Random
from base64 import b64encode, b64decode
from Crypto.Util.Padding import pad, unpad

key = '6b4f0a29d4bba86add88be9d'
iv = Random.new().read(DES3.block_size)
cipher = DES3.new(key, DES3.MODE_CBC, iv)
text = '12345678'.encode()
encrypted = cipher.encrypt(text)
encrypted_text = encrypted.hex()
print(encrypted_text)
# => f84f555b02e3ee24

可以看到,加密后的数据差别很大,至少是长度不同。所以解密部分不起作用。 如何修改Python代码以兼容Ruby? 不幸的是,数据可以通过 ruby 应用程序获得,所以我只能修改 Python。

python ruby encryption openssl
1个回答
0
投票

为了兼容 Ruby 代码,Python 代码缺少:

  • PKCS#7 填充
  • 零 IV(即由所有 0x00 值组成的 IV)。对于 Triple DES,块大小以及 IV 的大小为 8 字节。

这样,Python 代码必须修复如下:

from Crypto.Cipher import DES3
from Crypto import Random
from base64 import b64encode, b64decode
from Crypto.Util.Padding import pad, unpad

key = '6b4f0a29d4bba86add88be9d'
iv = b'\0' *  DES3.block_size                       # apply a zero IV
cipher = DES3.new(key, DES3.MODE_CBC, iv)
text = pad('12345678'.encode(), DES3.block_size)    # pad
encrypted = cipher.encrypt(text)
encrypted_text = encrypted.hex()
print(encrypted_text.upper())
# => 3B223AA60F1921F34CBBBAC209ACDCE4

通过此更改,Python 代码提供了 Ruby 代码的结果。


但是请注意,该代码存在漏洞:

  • 使用静态 IV 会导致在应用固定密钥时重复使用密钥/IV 对,这或多或少是一个严重的漏洞,具体取决于模式。为了避免这种情况,常见的方法是为每次加密生成随机 IV。这个 IV 不是秘密的,它与密文一起提供给加密方(通常是串联的)。
  • 实际上,密钥应该是随机字节序列而不是字符串,因为通常熵较低。如果密钥材料是字符串,则应将密钥派生函数(至少 PBKDF2)与随机的、非秘密的盐结合应用。
  • CBC 不是经过身份验证的加密。经过身份验证的加密除了保密性之外还保证了真实性/完整性。
  • 三重 DES 已弃用,当前标准是 AES。
© www.soinside.com 2019 - 2024. All rights reserved.