如何使用盐渍标头解密Blowfish密文?

时间:2011-07-04 03:58:17

标签: perl cryptography openssl blowfish

我有一些使用Perl的Crypt::CBC模块加密的密文,我希望在别处解密。

使用Crypt::CBC构造函数的“简单”版本生成密文,即:

use Crypt::CBC;
$cipher = Crypt::CBC->new( -key    => 'my secret key',
                           -cipher => 'Blowfish'
                          );

从阅读MAN页面,这种构造方法将采用简单的字符串键和随机盐来生成IV&用于加密的文字键,以及用盐嵌入标题。

  

“salt” - 将密码短语与   一个8字节的随机值              从中生成块密码密钥和IV              提供了密码。盐将附加到              允许解密的数据流的开头              给出正确的密码短语,重新生成密钥和IV。              此方法与当前版本的OpenSSL兼容。

我现在需要在另一个仅支持CBC解密的平台上解密密文,给出密文,文字密钥& IV。为了尝试生成文字密钥,IV& salt,我使用Crypt :: CBC生成如下值:

my $crypt = new Crypt::CBC(-key => 'my secret key', -cipher => 'Blowfish');
my $out = $crypt->decrypt($ciphertext);
my $literal_key = $crypt->key();
my $iv = $crypt->iv();
my $salt = $crypt->salt();

这里的解密是正确的,但我一直无法使用生成的文字密钥&四,解密密码;这会产生垃圾:

my $crypt2 = new Crypt::CBC(
    -literal_key => 1,
    -key => $literal_key,
    -cipher => 'Blowfish',
    -iv => $iv,
    -header => 'none');
my $rubbish - $crypt2->decrypt($ciphertext);

我无法提供文字键并使用盐渍标题,因此我对下一步行动感到迷茫。

如何解密此文本?

编辑:目标系统没有运行Perl,但我能够生成与上面的$ rubbish相同的值,所以我确定它使用相同的算法(CBC,Blowfish) )破译。

3 个答案:

答案 0 :(得分:1)

这可能有用。你的密钥长度必须是56个字节,而iv必须正好是8个字节长:

#!/usr/bin/perl

use strict;
use warnings;

use Crypt::CBC;

my $key = "x" x 56;
my $iv  = "x" x 8;

my $plaintext  = "this is just some normal text\n";
my $ciphertext = Crypt::CBC->new(
    -cipher      => 'Blowfish',
    -header      => 'none',
    -literal_key => 1,
    -key         => $key,
    -iv          => $iv,
)->encrypt($plaintext);

print Crypt::CBC->new(
    -cipher      => 'Blowfish',
    -header      => 'none',
    -literal_key => 1,
    -key         => $key,
    -iv          => $iv,
)->decrypt($ciphertext);

答案 1 :(得分:1)

要解密流,首先需要删除Crypt :: CBC的“salt”模式添加的标头。标题由8个字符Salted__组成,后跟8个字节的盐数据。

在perl中,这样的事情应该这样做:

my $crypt2 = new Crypt::CBC(
    -literal_key => 1,
    -key => $literal_key,
    -cipher => 'Blowfish',
    -iv => $iv,
    -header => 'none');
my $cleartext = $crypt2->decrypt(substr($ciphertext, 16));

答案 2 :(得分:1)

如果有人需要PHP中的_salted_key_and_iv函数 - 这里是:

function _salted_key_and_iv ($pass, $salt) {
        if(strlen($salt) != 8) {
            die("Salt must be 8 bytes long");
        }

        $key_len = 56;
        $iv_len  = 8;

        $desired_len = $key_len+$iv_len;

        $data  = '';
        $d = '';

        while (strlen($data) < $desired_len) {
            $d = pack("H*", md5($d . $pass . $salt));
            $data .= "$d";
        }

        return $data;
}