Openfire stores encrypted passwords in a database using blowfish encryption.
http://svn.igniterealtime.org/svn/repos/openfire/trunk/src/java/org/jivesoftware/util/
Openfire's code prepends the CBCIV passed with the output string. It also using Unicode as the character set. These together may be the problem area.
I don't know enough about Blowfish's internals to help more, sorry.
There is nothing wrong with your code, however to generate the same code as Openfire, you will need to add in two other items before the encrypted text.
Read "public String decryptString(String sCipherText)" in java code, it's all there. Also check the docs on how to use CBCIV in PHP.
Here's a class I made, it encrypts and decrypts properly.
Note, you need to save / [pre/app]end the IV in order to reproduce results.
Some test vectors for the java code would be nice.
<?php
/**
* Emulate OpenFire Blowfish Class
*/
class OpenFireBlowfish
{
private $key;
private $cipher;
function __construct($pass)
{
$this->cipher = mcrypt_module_open('blowfish','','cbc','');
$this->key = pack('H*',sha1($pass));
}
function encryptString($plaintext, $iv = '')
{
if ($iv == '') {
$iv = mcrypt_create_iv(mcrypt_enc_get_iv_size($this->cipher));
}
else {
$iv = pack("H*", $iv);
}
mcrypt_generic_init($this->cipher, $this->key, $iv);
$bs = mcrypt_enc_get_block_size($this->cipher); // get block size
$plaintext = mb_convert_encoding($plaintext,'UTF-16BE'); // set to 2 byte, network order
$pkcs = $bs - (strlen($plaintext) % $bs); // get pkcs5 pad length
$pkcs = str_repeat(chr($pkcs), $pkcs); // create padding string
$plaintext = $plaintext.$pkcs; // append pkcs5 padding to the data
$result = mcrypt_generic($this->cipher, $plaintext);
mcrypt_generic_deinit($this->cipher);
return $iv.$result;
}
function decryptString($ciphertext)
{
$bs = mcrypt_enc_get_block_size($this->cipher); // get block size
$iv_size = mcrypt_enc_get_iv_size($this->cipher);
if ((strlen($ciphertext) % $bs) != 0) { // check string is proper size
return false;
}
$iv = substr($ciphertext, 0, $iv_size); // retrieve IV
$ciphertext = substr($ciphertext, $iv_size);
mcrypt_generic_init($this->cipher, $this->key, $iv);
$result = mdecrypt_generic($this->cipher, $ciphertext); // decrypt
$padding = ord(substr($result,-1)); // retrieve padding
$result = substr($result,0,$padding * -1); // and remove it
mcrypt_generic_deinit($this->cipher);
return $result;
}
function __destruct()
{
mcrypt_module_close($this->cipher);
}
}
$enckey = "1uY40SR771HkdDG";
$enciv = 'd3f499857b40ac45';
$javastring = 'd3f499857b40ac45c41828ccaa5ee1f90b19ca4e0560d1e2dcf4a305f219a4a2342aa7364e9950db';
$a = new OpenFireBlowfish($enckey);
$encstring = bin2hex($a->encryptString('stackoverflow',$enciv));
echo $encstring . "\n";
echo $a->decryptString(pack("H*", $encstring)) . "\n";
$b = new OpenFireBlowfish($enckey);
echo $b->decryptString(pack("H*", $javastring)) . "\n";