Heim  >  Artikel  >  Backend-Entwicklung  >  Blowfish加密,诀别使用PHP和C++实现,但结果不同.

Blowfish加密,诀别使用PHP和C++实现,但结果不同.

WBOY
WBOYOriginal
2016-06-13 13:10:49860Durchsuche

Blowfish加密,分别使用PHP和C++实现,但结果不同...
先是MD5实验,结果相同,但使用Blowfish实验,怎么做也成功不了
调用如下:

PHP code
<!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

--><?php $cipher = mcrypt_module_open(MCRYPT_BLOWFISH, '', MCRYPT_MODE_ECB, '');

    $iv   = '00000000';
    $key  = "strkey11";

    $stext = '38A0E9312DDA8F7C16B9A12159168C76';
    $stext = md5($stext, true);
    //经过调试知道,在这时$stext的值与C++中MD5后的结果一致

    if (mcrypt_generic_init($cipher, $key, $iv) != -1)
    {
        $dtext = mcrypt_generic($cipher,$stext );
        mcrypt_generic_deinit($cipher);

        // Display the result in hex.
        printf("blowfish encrypted:<br>%s<br><br>",strtoupper(bin2hex($dtext)));
    }
    mcrypt_module_close($cipher);


C++的是这样:
C/C++ code
<!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

-->    MD5_CTX md5;
    unsigned char str[16];
    md5.MD5String(strSource.c_str() ,str);

    BlockCipher *bf;
    char key[] = "strkey11";              //Key
    bf = new BlowFish();
    bf->setKey((void *)key, 8*8);

    bf->encrypt((void *)str, 8);      //unsigned char str[16];
    bf->encrypt((void *)(str+8), 8);
    char temp1[4] = {0};
    char buff1[128] = {0};
    for(int i = 0;i


------解决方案--------------------
$iv = '00000000'; ???
按 bf->setKey((void *)key, 8*8); 理解
应该是
$iv = "\x00\x00\x00\x00\x00\x00\x00\x00";
吧?

------解决方案--------------------
IV is ignored in ECB. IV MUST exist in CFB, CBC, STREAM, nOFB and OFB modes.
MCRYPT_MODE_ECB的模式,$iv是忽略的,应该不是这个问题。

好像是加密之前要padding,你试试看
$size = mcrypt_get_block_size(MCRYPT_BLOWFISH, MCRYPT_MODE_ECB);
$input = pkcs5_pad($input, $size); 

function pkcs5_pad ($text, $blocksize)
{
$pad = $blocksize - (strlen($text) % $blocksize);
return $text . str_repeat(chr($pad), $pad);
}

function pkcs5_unpad($text)
{
$pad = ord($text{strlen($text)-1});
if ($pad > strlen($text)) return false;
if (strspn($text, chr($pad), strlen($text) - $pad) != $pad) return false;
return substr($text, 0, -1 * $pad);
}
------解决方案--------------------
c++的结果是不是有问题,这里有个在线blowfish加密的,你可以验证一下
http://webnet77.com/cgi-bin/helpers/blowfish.pl
------解决方案--------------------

首先你要弄清楚到底是PHP错了还是C++错了,我之前用bin2hex确实不对,但是md5之后是二进制数据没法验证,
你能不能不要用md5直接字符abcdefgh, 加密后是什么?

网页结果是
明文 abcdefgh
密文 5B4148819C51DCB5
------解决方案--------------------
我用了PHP的在线解码
http://www.tools4noobs.com/online_tools/decrypt/

5B4148819C51DCB5能解密出来,但是12DB6214F5EAB031解不出来

是不是C++程序有什么不一样?只要能加密解密不能算错,但是要互相能解密加密就必须遵循一样的算法。

同样的对称算法,同样的key,不大可能密文是不一样的,除了有些随机干扰。但是从blowfish的算法看,
并没有随机干扰,是不是有可能是pbox,sbox定义的不一样?
------解决方案--------------------
关于C++代码,有两个问题你可以确认一下
1)bf->setKey((void *)key, 8*8); 第二个参数应该是key的长度,为什么是8*8?
2)PHP有设置ECB模式,但是c++里没有,是不是缺省就是ECB?
------解决方案--------------------
我找到原因了,你的算法跟PHP的blowfish算法不一样,c++的算法是blowfish-compat

所以改成$cipher = mcrypt_module_open('blowfish-compat', '', MCRYPT_MODE_ECB, '');
这样就应该可以了。
Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn