2

我需要能够在 Ruby 客户端和 Python 服务器之间发送加密数据(反之亦然),并且在使用ruby​​-aes gem/library 时遇到了问题。该库非常易于使用,但我们在它和 Python 的 pyCrypto AES 库之间传递数据时遇到了麻烦。当这些库是唯一被使用的库时,它们似乎很好,但它们似乎不能很好地跨越语言边界。有任何想法吗?

编辑:我们正在通过 SOAP 进行通信,并且还尝试将二进制数据转换为 base64 无济于事。此外,更重要的是两者之间的加密/解密几乎但不完全相同(例如,长度相差一或解密字符串末尾有额外的垃圾字符)

4

5 回答 5

5

(例如,长度相差一或解密字符串末尾有多余的垃圾字符)

我错过了那一点。您的加密/解密没有问题。这听起来像一个填充问题。AES 始终以 128 位块的形式对数据进行编码。如果您的数据长度不是 128 位的倍数,则应在加密之前填充数据,并且在加密后需要删除/忽略填充。

于 2008-10-13T13:12:42.890 回答
3

原来发生的事情是 ruby​​-aes 自动填充数据以填充 16 个字符,并在最终字符串的末尾粘贴一个空字符作为分隔符。PyCrypto 要求你做 16 个字符的倍数,这就是我们弄清楚 ruby​​-aes 在做什么的方式。

于 2008-10-13T07:17:02.110 回答
2

如果没有更多信息,甚至很难猜测发生了什么......

如果我是你,我会在你的 Python 和 Ruby 程序中检查:

  1. 键是相同的(显然)。将它们转储为十六进制并比较每个字节。
  2. 初始化向量是相同的。这是pyCryptoIV中的参数。AES.new()也将它们转储为十六进制。
  3. 模式是一样的。pyCrypto 中mode的参数。AES.new()

IVpyCrypto 中的and有默认值mode,但不要相信它们与 Ruby 实现中的相同。使用一种更简单的模式,例如 CBC。我发现不同的库对复杂模式(例如 PTR)的工作方式有不同的解释。

维基百科有一篇关于如何分组密码模式的精彩文章。

于 2008-10-13T07:05:19.963 回答
1

有点取决于您传输加密数据的方式。您可能正在用一种语言编写文件,然后尝试从另一种语言中读取它。Python(尤其是在 Windows 上)要求您为二进制文件指定二进制模式。所以在 Python 中,假设你想在那里解密,你应该像这样打开文件:

f = open('/path/to/file', 'rb')

“b”表示二进制。如果您要从 Python 将加密数据写入文件:

f = open('/path/to/file', 'wb')
f.write(encrypted_data)
于 2008-10-13T05:42:44.530 回答
1

基本上是 Hugh 上面所说的:检查 IV、密钥大小和链接模式,以确保一切都相同。

独立测试双方,编码一些信息并检查 Ruby 和 Python 是否以相同的方式结束它。您假设问题与加密有关,但它可能只是像发送加密数据一样简单,puts其中将随机换行符放入数据中。一旦您确定他们正确加密了数据,请检查您是否收到了您认为您发送的内容。继续一步一步,直到找到破坏数据的阶段。

另外,我建议使用 ruby​​ 标准库中包含的 openssl 库,而不是使用外部 gem。

于 2008-10-13T13:01:08.483 回答