我们的c++项目和php项目共同使用了blowfish-compat方式加密通信,但php升级到php7后,mcrypt扩展被废弃了。但openssl不支持blowfish-compat方式,于是多方查找和调试后,有了两个解决办法:
- 找到一个BlowFish的源码(非compat),将其改造成blowfish-compat
2.调用openssl的BF-ECB类型加解密,但在前后进行字节序的调整。
前者只需要将 https://github.com/themattharris/PHP-Blowfish/blob/master/blowfish.php 代码中 'N2' 替换成 'V2'即可。
也可以直接使用我改过的版本:https://gist.github.com/k1988/c5c7f1bac1f94547b11c2a258c2a8ba3
。
后者,基于网上的一个代码改进如下:
<?php
// 使用内置openssl或mcrypt实现blowfish加解密的函数
$plaintext = '{123}';
// 替换字节序,并对齐8字节
function change_net_order($data){
if ($m = strlen($data)%8)
$data .= str_repeat("\x00", 8 - $m);
$data = unpack('V*',$data);
foreach($data as &$v){
$v = pack("N", $v);
}
$data = join('', $data);
return $data;
}
function encrypt($data, $key)
{
$l = strlen($key);
if ($l < 16)
$key = str_repeat($key, ceil(16/$l));
if (function_exists('mcrypt_encrypt'))
$val = mcrypt_encrypt(MCRYPT_BLOWFISH_COMPAT, $key, $data, MCRYPT_MODE_ECB);
else
{
$data = change_net_order($data);
$val = openssl_encrypt($data, 'BF-ECB', $key, OPENSSL_RAW_DATA | OPENSSL_NO_PADDING);
$val = change_net_order($val);
}
return $val;
}
function decrypt($data, $key)
{
$l = strlen($key);
if ($l < 16)
$key = str_repeat($key, ceil(16/$l));
if (function_exists('mcrypt_encrypt'))
$val = mcrypt_decrypt(MCRYPT_BLOWFISH, $key, $data, MCRYPT_MODE_ECB);
else
{
$data = change_net_order($data);
$val = openssl_decrypt($data, 'BF-ECB', $key, OPENSSL_RAW_DATA | OPENSSL_NO_PADDING);
$val = change_net_order($val);
}
return $val;
}
$data = $plaintext;
$encrypted = encrypt($data, '1234567890123456');
echo "encryped => ". bin2hex($encrypted) ." <br/>";
echo "encryped-base64 => ". base64_encode($encrypted) ." <br/>";
echo "raw => ". trim(decrypt($encrypted, '1234567890123456')) ." <br/>";
网友评论