Search code examples
pythonjavaencryptionbyteblowfish

Convert Blowfish Encryption from Java to Python


I am attempting to convert my Java Blowfish encryption algorithm into Python. I am using the blowfish package which takes the same parameters as the Java library. They both execute successfully, however, I do not get the same result back.

Java code

    public static void main(String[] args) {

    try {
        String mainText = "hello world";
        String stBlowfishIv = "zzyyxxaa";
        String stBlowfishKey = "how.good";

        byte[] byteString;
        IvParameterSpec iv = new IvParameterSpec(stBlowfishIv.getBytes());
        SecretKey key = new SecretKeySpec(stBlowfishKey.getBytes(), "Blowfish");
        Cipher c = Cipher.getInstance("Blowfish/CFB/NoPadding");
        c.init(Cipher.ENCRYPT_MODE, key, iv);
        byteString = c.doFinal(mainText.getBytes());
        System.out.println(Arrays.toString(byteString));
    }
    catch (GeneralSecurityException e) {
        throw new RuntimeException(e);
    }
}

Output

[47, -19, 48, -42, 19, 126, -105, 66, 21, -126, -44]

Python code

    def encrypt(self, initVector="zzyyxxaa", key="how.good"):

    totalString = "hello world"
    initVectorBytes = bytes(initVector, 'utf-8')
    keyBytes = bytes(key, 'utf-8')
    totalStringBytes = bytes(totalString, 'utf-8')

    cipher = blowfish.Cipher(keyBytes)

    dataEncrypted = b"".join(cipher.encrypt_cfb(totalStringBytes, initVectorBytes))
    print(dataEncrypted)

    for byte in dataEncrypted:
        print(byte, end=' ')

Output

b'/\xed0\xd6\x13~\x97B\x15\x82\xd4'

47 237 48 214 19 126 151 66 21 130 212

Some assistance or guidance would be much appreciated.


Solution

  • Java Output

    [47, -19, 48, -42, 19, 126, -105, 66, 21, -126, -44]
    

    Python Output

    47 237 48 214 19 126 151 66 21 130 212
    

    These represent the exact same bit pattern, therefore your code is working.

    The apparent difference comes from the fact that in Java the byte type is signed. Notice that the only differences are the output bytes that display as negative values in the Java output.

    Taking the first difference for example, -19 vs 237, the bit pattern for both of these is 0xED, or binary 1110 1101. If interpreted as unsigned, the value is 237, but if interpreted as signed, the value is -19.