Hi,
I'm trying to understand why there is a difference between Ruby and
Python when using Blowfish encryption in ECB mode. Using the same
algorithm parameters, and the same input, the encrypted output is
completely different.
Behold these two code samples:
RUBY==================
require 'digest'
require 'openssl'
cleartext = 'whatevs'
md5 = Digest::MD5.new
md5.update(cleartext)
payload = (md5.digest + cleartext).ljust(0x80, "\x00")
puts "plaintext: " + payload.unpack('H*')[0]
secret_key = "supersecretsupersecret"
cipher = OpenSSL::Cipher::Cipher.new("bf-ecb").send :encrypt
cipher.key = secret_key
cipher.padding = 0
binary_data = (cipher.update(payload) << cipher.final)
puts "ciphertext: " + binary_data.unpack('H*')[0]
cipher = OpenSSL::Cipher::Cipher.new("bf-ecb").send :decrypt
cipher.key = secret_key
cipher.padding = 0
str = (cipher.update(binary_data) << cipher.final)
puts "decrypted: " + str.unpack('H*')[0]
RUBY==================
PYTHON================
from Crypto.Cipher import Blowfish
from Crypto.Hash import MD5
import binascii
cleartext = 'whatevs'
md5_key = MD5.new(cleartext).digest()
payload = (md5_key + cleartext).ljust(0x80, "\x00")
print "plaintext: " + binascii.hexlify(payload)
secret_key = "supersecretsupersecret"
ciphertext = Blowfish.new(secret_key, Blowfish.MODE_ECB).encrypt(payload)
print "ciphertext: " + binascii.hexlify(ciphertext)
print "decrypted: " + binascii.hexlify(Blowfish.new(secret_key,
1).decrypt(ciphertext))
PYTHON================
Running these, I get the following:
~ > ruby /tmp/test.rb
plaintext:
030fa889aa00fc6554023a9aad8c9ca177686174657673000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
ciphertext:
e7fd839dbc4762226b1086170e8227c2e2e4c54ee4f51fbd2e4bd6de84eafc452e4bd6de84eafc452e4bd6de84eafc452e4bd6de84eafc452e4bd6de84eafc452e4bd6de84eafc452e4bd6de84eafc452e4bd6de84eafc452e4bd6de84eafc452e4bd6de84eafc452e4bd6de84eafc452e4bd6de84eafc452e4bd6de84eafc45
decrypted:
030fa889aa00fc6554023a9aad8c9ca177686174657673000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
~ > python /tmp/test.py
plaintext:
030fa889aa00fc6554023a9aad8c9ca177686174657673000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
ciphertext:
992f5dad8650fb447416693d8d1f07e869c63d8798234e933bb878160d775aee3bb878160d775aee3bb878160d775aee3bb878160d775aee3bb878160d775aee3bb878160d775aee3bb878160d775aee3bb878160d775aee3bb878160d775aee3bb878160d775aee3bb878160d775aee3bb878160d775aee3bb878160d775aee
decrypted:
030fa889aa00fc6554023a9aad8c9ca177686174657673000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
As you can see, the plaintext and decrypted ciphertext are the same, but
the ciphertexts are different.
Why is this happening? This is a major pain as it means I cannot interop
with Python. There are other gems for Blowfish encryption, but none of
them have ECB mode (which is the one I'm interested in - and yes, before
you say it, I know ECB is insecure).
Am I doing something wrong? Or is this a deeper problem in Python or Ruby?
Regards,
Pedro