【问题标题】:PHP blowfish cbc VS Pearl CryptPHP河豚cbc VS珍珠地穴
【发布时间】:2019-02-01 17:30:19
【问题描述】:

我正在使用 openssl_encrpyt 在 PHP 中加密客户端号码。

$value = '01715034842';
$key = 'pi3kn3W@k@cj3';                
$iv = 'Toy@dtv!';
$cipher = 'bf-cbc';

$crypted = openssl_encrypt($value, $cipher, $key, true, $iv);
$hashValue = unpack('H*',$crypted);

最终结果是: 0b6b81176ac7c298ebcb294f0a581539

还有我的朋友在 Pearl 编程其他部分。而且他还使用相同的密钥和使用 Blowfish 对相同的数字进行编码(他正在使用珍珠库:https://metacpan.org/pod/release/LDS/Crypt-CBC-2.30/CBC.pm):

use Crypt::CBC;
use Crypt::Blowfish;


## szyfrowanie
my $key = 'pi3kn3W@k@cj3';
my $iv = 'Toy@dtv!';

my $cipher = Crypt::CBC->new(   -key    => $key,
                                -iv => $iv,
                                -header => 'none',
                                -cipher => 'Blowfish'
                            );
sub mkHash {
        my  $crypt = $cipher->encrypt_hex($_[0]);
#        print 'Hash: '.$crypt."\n";
        return $crypt;
}


sub deHash {
        my $crypt = $cipher->decrypt_hex($_[0]);
       # print 'string: '.$crypt."\n";
        return $crypt;
}

my $clientHash = mkHash($smc);

而他对于同一组数据得到不同的结果: c5377bcf0f55af641709c35928350576

所以我们不能广泛使用这种语言。 这取决于编程语言的差异?或者这是我的代码或语言中的错误? 我认为当我们使用相同的数据集和相同的加密 (BlowFish CBC) 时,我们应该在每种语言中得到相同的结果。

期待对此案的意见。

最好的 巴特克。

【问题讨论】:

    标签: php openssl crypt blowfish


    【解决方案1】:

    工作脚本

    以下 PHP 和 Perl 脚本展示了如何为两种语言实现相同的输出。我将在下面解释一些细节。

    PHP:

    $value = '01715034842';
    $cipher = 'bf-cbc';
    $key = '12345678901234567890123456789012345678901234567890123456';
    $option = OPENSSL_RAW_DATA;
    $iv = 'Toy@dtv!';
    
    $crypted = openssl_encrypt($value, $cipher, $key, $option, $iv);
    echo($crypted)
    

    Perl:

    use Crypt::CBC;
    use Crypt::Blowfish;
    
    my $value = '01715034842';
    my $key = '12345678901234567890123456789012345678901234567890123456';
    my $iv = 'Toy@dtv!';
    
    my $cipher = Crypt::CBC->new(   -literal_key => 1,
                                    -key         => $key,
                                    -iv          => $iv,
                                    -header      => 'none',
                                    -cipher      => 'Blowfish'
                                );
    
    my $crypted = $cipher->encrypt($value);
    print $crypted;
    

    在两个输出上使用diff 没有区别,表明它们是相同的:

    $ diff <(php encrypt.php) <(perl encrypt.pl)
    $
    

    解释所需更改的详细信息

    以下部分解释了与原始代码相比所需的更改。

    加密密钥

    PHP openssl_encrypt() 函数总是需要一个原始密钥。您给它的字节是用作加密密钥的字节。另一方面,Perl CBCexpects a passphrase by default,它将从中派生加密密钥 by doing an MD5 hash。如果您希望该类使用您的原始字节作为加密密钥,您必须将参数literal_key 设置为1

    完成此操作后,CBC 类期望密钥是加密方案所需的确切字节数,which the CBC class assumes to be 56 for the Crypt::Blowfish implementation。因此脚本中的调整键。否则你会得到的错误是If specified by -literal_key, then the key length must be equal to the chosen cipher's key length of 56 bytes

    输出格式

    PHP openssl_encrypt() 函数默认返回 base64 编码字符串,CBC 类返回原始字节。使这一点保持一致的一种方法是在 PHP 中设置 OPENSSL_RAW_DATA 选项。

    检查密文

    如果您想检查可读格式的密文,您可以在末尾添加自己的打印例程或将输出通过管道传输到hexdumpxxd 等工具中

    $ php encrypt.php | xxd
    00000000: 5f35 3205 74e8 dcaa 2f05 9aa4 366e ef8b  _52.t.../...6n..
    $ perl encrypt.pl | xxd
    00000000: 5f35 3205 74e8 dcaa 2f05 9aa4 366e ef8b  _52.t.../...6n..
    

    【讨论】:

    • 谢谢,帮了大忙。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-01-04
    • 2012-08-13
    • 2016-02-29
    • 1970-01-01
    • 1970-01-01
    • 2013-03-08
    • 1970-01-01
    相关资源
    最近更新 更多