0

I'm trying pass data between applications that was encrypted using the Horde/phpmyadmin blowfish.php library, using mcrypt instead. If I do something like:

$key = "qwerty";
$data = "12345678";

$pma_cipher = new Horde_Cipher_blowfish;

print base64_encode( mcrypt_encrypt( MCRYPT_BLOWFISH, $key, $data, MCRYPT_MODE_CBC ) );
print PMA_blowfish_encrypt( $data, $key );
print base64_encode( $pma_cipher->encryptBlock( $data, $key ) );
print base64_encode( $pma_cipher->encryptBlock( $data, $key ) );

The output is

pC+XbHWnqIg= // mcrypt
pC+XbHWnqIg= // PMA blowfish
pC+XbHWnqIg= // OK
WwkIWeYzlHw= // next block is different

Furthermore, if I change the data:

$key = "qwerty";
$data = "123456789";

$pma_cipher = new Horde_Cipher_blowfish;

print base64_encode(mcrypt_encrypt(MCRYPT_BLOWFISH, $key, $data, MCRYPT_MODE_CBC));
print PMA_blowfish_encrypt( $data, $key );

I now get:

pC+XbHWnqIjaCTiQlKkXRQ==
pC+XbHWnqIg99GXjyWLMmA==

It seems that the Horde/PMA version is changing the key every block.

Is there a way to tweak the mcrypt calls to make the two libraries cross-compatible, or should I just pick one or the other and adjust things accordingly?

Andrew
  • 192
  • 10

1 Answers1

0

The blowfish s-boxes vary by design each time the key is set on the same instance. This is how bcrypt hashing works.

I believe what you should be doing instead is:

$pma_cipher = new Horde_Cipher_blowfish;

$pma_cipher->setKey( $key ); // Set the key only once!

print base64_encode( mcrypt_encrypt( MCRYPT_BLOWFISH, $key, $data, MCRYPT_MODE_CBC ) );
print PMA_blowfish_encrypt( $data, $key );
print base64_encode( $pma_cipher->encryptBlock( $data ) ); // specifying the key resets it
print base64_encode( $pma_cipher->encryptBlock( $data ) ); // specifying the key resets it

This should give you the same result each time.

In terms of your other question though:

should I just pick one or the other and adjust things accordingly

If possible you should use the mcrypt_* functions as they are much faster than the raw PHP implementation used by PMA. Blowfish is notoriously slow (at least in key setup) in the first place; doing that in PHP instead of the C library should only be a fallback.

mjec
  • 1,817
  • 12
  • 20
  • I'm trying to be compatible to code that is specifying the key for every block of 8 bytes - can I respecify the key with the mcrypt functions? – Andrew Jul 09 '12 at 02:05
  • Not really. You can do key mixing manually (by copying the function source from `Horde_Cipher_blowfish`) or you can re-initialize `$pma_cipher` prior to doing each `encryptBlock()` call. – mjec Jul 13 '12 at 06:32