Which AES library to use in Ruby/Python?

限于喜欢 提交于 2019-12-06 06:14:25

(e.g., the lengths differ by one or there is extra garbage characters on the end of the decrypted string)

I missed that bit. There's nothing wrong with your encryption/decryption. It sounds like a padding problem. AES always encodes data in blocks of 128 bits. If the length of your data isn't a multiple of 128 bits the data should be padded before encryption and the padding needs to be removed/ignored after encryption.

Turns out what happened was that ruby-aes automatically pads data to fill up 16 chars and sticks a null character on the end of the final string as a delimiter. PyCrypto requires you to do multiples of 16 chars so that was how we figured out what ruby-aes was doing.

It's hard to even guess at what's happening without more information ...

If I were you, I'd check that in your Python and Ruby programs:

  1. The keys are the same (obviously). Dump them as hex and compare each byte.
  2. The initialization vectors are the same. This is the parameter IV in AES.new() in pyCrypto. Dump them as hex too.
  3. The modes are the same. The parameter mode in AES.new() in pyCrypto.

There are defaults for IV and mode in pyCrypto, but don't trust that they are the same as in the Ruby implementation. Use one of the simpler modes, like CBC. I've found that different libraries have different interpretations of how the mode complex modes, such as PTR, work.

Wikipedia has a great article about how block cipher modes.

Kind of depends on how you are transferring the encrypted data. It is possible that you are writing a file in one language and then trying to read it in from the other. Python (especially on Windows) requires that you specify binary mode for binary files. So in Python, assuming you want to decrypt there, you should open the file like this:

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

The "b" indicates binary. And if you are writing the encrypted data to file from Python:

f = open('/path/to/file', 'wb')
f.write(encrypted_data)

Basically what Hugh said above: check the IV's, key sizes and the chaining modes to make sure everything is identical.

Test both sides independantly, encode some information and check that Ruby and Python endoded it identically. You're assuming that the problem has to do with encryption, but it may just be something as simple as sending the encrypted data with puts which throws random newlines into the data. Once you're sure they encrypt the data correctly, check that you receive exactly what you think you sent. Keep going step by step until you find the stage that corrupts the data.

Also, I'd suggest using the openssl library that's included in ruby's standard library instead of using an external gem.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!