Search code examples
javaphpencryptionblowfish

Blowfish encryption - encrypted in php and java, I got different encrypted values


The encryption test data:

key: 'ABC';
data:'1234567';
algorithm:  MCRYPT_BLOWFISH;
mode: MCRYPT_MODE_ECB;

PHP code

$key  = 'ABC';
$data = '1234567';
$alg  = MCRYPT_BLOWFISH;
$mode = MCRYPT_MODE_ECB;

$encrypted_data = mcrypt_encrypt($alg, $key, $data, $mode);

$phpgeneratedtoken  = base64_encode($encrypted_data);

print "PHP generated token: " . $phpgeneratedtoken."   ";
// return
// In6uDpDqt1g=

// Decode the token just generated by php

$decoded = mcrypt_decrypt($alg,$key,base64_decode("In6uDpDqt1g="),$mode);
print "Decoded from php generated token:" . $decoded."    ";

//return
//1234567

// This is the encrypted token generated by java with same key and value
$javageneratedtoken  = "Cg8qY4gRMaI=";

// Decode the token generated by Java
$decoded = mcrypt_decrypt($alg,$key,base64_decode("Cg8qY4gRMaI="),$mode);
print "Decoded from Java Generated token: " . $decoded."    ";
// return
// 1234567

// Both tokens generated by java and php, are decrypted back to the same value.

Java Code:

import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;

public class BlowfishTest {

    public static void main(String[] args) throws Exception {
        encrypt("1234567");
        decrypt("In6uDpDqt1g=");
    }

    private static void encrypt(String password) throws Exception {
        byte[] keyData = ("ABC").getBytes();
        SecretKeySpec secretKeySpec = new SecretKeySpec(keyData, "Blowfish");
        Cipher cipher = Cipher.getInstance("Blowfish");
        cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec);
        byte[] hasil = cipher.doFinal(password.getBytes());
        System.out.println(new BASE64Encoder().encode(hasil));
    }

    private static void decrypt(String string) throws Exception {
        byte[] keyData = ("ABC").getBytes();
        SecretKeySpec secretKeySpec = new SecretKeySpec(keyData, "Blowfish");
        Cipher cipher = Cipher.getInstance("blowfish/ecb/nopadding");
        cipher.init(Cipher.DECRYPT_MODE, secretKeySpec);
        byte[] hasil = cipher.doFinal(new BASE64Decoder().decodeBuffer(string));
        System.out.println(new String(hasil));
    }
}

The PHP generated encrypted value is: In6uDpDqt1g=.

The Java generated encrypted value is: Cg8qY4gRMaI=.

The issue is at Java Code's

Cipher cipher = Cipher.getInstance("blowfish");

I need to find a way to make my PHP generated encrypted value the same as the Java generated encrypted value.

Both encrypted values I can decrypt them back in PHP. Both encrypted values I could decrypt them back in java too, ONLY IF I set,

Cipher cipher = Cipher.getInstance("blowfish/ecb/nopadding");

But when I try to decrypt PHP encrypted value, In6uDpDqt1g=, in Java.

If I set,

Cipher cipher = Cipher.getInstance("blowfish");

I got the error:

"Given final block not properly padded".

The problem is I am supposed to use PHP to encrypt value, and my client would use java to decrypt value. With the setup Cipher cipher = Cipher.getInstance("blowfish") to decrypt my value.

So I want to find a way that I should use PHP to get the same encrypted value as Java, with Cipher cipher = Cipher.getInstance("Blowfish"), would get.

If there is no such solution, then I would have to ask my client to change his java codes to use

Cipher cipher = Cipher.getInstance("blowfish/ecb/nopadding");

Solution

  • OK, I find my answer. I need to change my php code to

    $key  = 'ABC';
    $data = '1234567';
    $alg  = MCRYPT_BLOWFISH;
    $mode = MCRYPT_MODE_ECB;
    
    $blocksize = mcrypt_get_block_size('blowfish', 'ecb'); // get block size 
    $pkcs = $blocksize - (strlen($data) % $blocksize); // get pkcs5 pad length 
    $data.= str_repeat(chr($pkcs), $pkcs);
    
    $encrypted_data = mcrypt_encrypt($alg, $key, $data, $mode);
    
    $phpgeneratedtoken  = base64_encode($encrypted_data);
    
    print "PHP generated token: " . $phpgeneratedtoken."   ";
    // return
    // Cg8qY4gRMaI=