I have a legacy implementation of blowfish in java that I am trying to port to Python.
Java:
import blowfishj.*;
import org.apache.commons.codec.binary.Hex;
private static byte[] EncryptBlowFish(byte[] sStr, String sSecret) {
byte[] key = sSecret.getBytes();
byte[] cipher = new byte[sStr.length];
BlowfishECB blowfish = new BlowfishECB(key, 0, key.length);
blowfish.encrypt(sStr, 0, cipher, 0, sStr.length);
return (new String(Hex.encodeHex(cipher)));
}
Python:
from Crypto.Cipher import Blowfish
import binascii
def encrypt(encr_str, key_str):
cipher = Blowfish.new(key_str, Blowfish.MODE_ECB)
return binascii.hexlify(cipher.encrypt(encr_str)).decode('utf-8')
If the string to be encrypted is "12345678" and the key is "1234567890123456", the java code outputs "e00723bbb58234aa" and the python code outputs "61d2570dc6e09632".
Since the java code is legacy, I can't touch it. This indicates there's a problem in pycrypto's implementation of blowfish. However, I can confirm the accepted answer here works. Not sure why though. I tried both pycrypto as well as this blowfish module with the same result.
Any ideas how to replicate the same blowfish output in Python as the legacy java code?
All credit to @Kai Iskratsch for pointing in the right direction.
Reference:
Here's the code that worked for me.
Python:
from Crypto.Cipher import Blowfish
from binascii import hexlify
def encrypt(key, string):
"""
Encrypts input string using BlowFish-Compat ECB algorithm.
:param key: secret key
:param string: string to encrypt
:return: encrypted string
"""
cipher = Blowfish.new(key, Blowfish.MODE_ECB)
return hexlify(_reverse_bytes(cipher.encrypt(_reverse_bytes(string)))).decode('utf-8')
@staticmethod
def _reverse_bytes(data):
"""
Takes data and reverses byte order to fit blowfish-compat format. For example, using _reverse_bytes('12345678')
will return 43218765.
:param data as bytes
:return: reversed bytes
"""
data_size = 0
for n in data:
data_size += 1
reversed_bytes = bytearray()
i = 0
for x in range(0, data_size // 4):
a = (data[i:i + 4])
i += 4
z = 0
n0 = a[z]
n1 = a[z + 1]
n2 = a[z + 2]
n3 = a[z + 3]
reversed_bytes.append(n3)
reversed_bytes.append(n2)
reversed_bytes.append(n1)
reversed_bytes.append(n0)
return bytes(reversed_bytes)