1

Perl Crypt::CBC (Rijndael,cbc) で暗号化された暗号化文字列があります。元の平文は Crypt::CBC の encrypt_hex() メソッドで暗号化されています。

$encrypted_string = '52616e646f6d49567b2c89810ceddbe8d182c23ba5f6562a418e318b803a370ea25a6a8cbfe82bc6362f790821dce8441a790a7d25d3d9ea29f86e6685d0796d';

使用された 32 文字のキーがあります。

mcrypt は PHP に正常にコンパイルされていますが、PHP で文字列を復号化するのに非常に苦労しています。私はちんぷんかんぷんを返し続けます。

unpack('H*', $encrypted_string) すると、'RandomIV' の後にバイナリのように見えるものが表示されます。

IV を正しく抽出して、実際の暗号化されたメッセージを分離できないようです。自分の情報を提供していないことはわかっていますが、他にどこから始めればよいかわかりません。

$cipher = 'rijndael-256';
$cipher_mode = 'cbc';

$td = mcrypt_module_open($cipher, '', $cipher_mode, '');

$key = '32 characters'; // Does this need to converted to something else before being passed?
$iv = ??  // Not sure how to extract this from $encrypted_string.
$token = ?? // Should be a sub-string of $encrypted_string, correct?

mcrypt_generic_init($td, $key, $iv);
$clear = rtrim(mdecrypt_generic($td, $token), '');
mcrypt_generic_deinit($td); 
mcrypt_module_close($td);

echo $clear;

どんな助け、正しい方向への指針も大歓迎です。さらに情報を提供する必要がある場合はお知らせください。

4

3 に答える 3

2

使用する IV は、CBC::Crypt によってランダムに生成されるだけだと思います。私が正しく、ドキュメントを正しく読んでいる場合、それは解凍された文字列の最初の 32 バイトです。

良いキーでこれを試してください:

$cipher = 'rijndael-256';
$cipher_mode = 'cbc';

$td = mcrypt_module_open($cipher, '', $cipher_mode, '');

$key = '32 characters'; // Does this need to converted to something else before being passed?

$unpacked = pack('H*', '52616e646f6d49567b2c89810ceddbe8d182c23ba5f6562a418e318b803a370ea25a6a8cbfe82bc6362f790821dce8441a790a7d25d3d9ea29f86e6685d0796d');


$iv = substr($unpacked, 0, 32);
$token = substr($unpacked, 32);

mcrypt_generic_init($td, $key, $iv);
$clear = rtrim(mdecrypt_generic($td, $token), '');
mcrypt_generic_deinit($td); 
mcrypt_module_close($td);

echo $clear;
于 2010-04-09T15:09:46.557 に答える
1

この回答は、Crypt::CBC のソルト モードに対するものであり、randomIV モードではありませんが、これは解決策を検索したときにたどり着いたページなので、他の人もそうかもしれません。

この perl コードを使用する場合:

  my $cipher = Crypt::CBC->new(
                -key    =>  $password,
                -cipher => 'Rijndael',
                -salt => 1,
                -header => 'salt',
              ) || die "Couldn't create CBC object";
  $string = $cipher->encrypt_hex($input);

(または、デフォルトでこれらの値を持つソルトとヘッダーがなくても) Perl は、OpenSSL に準拠するためのハッシュを作成します。これを読み取る方法を知っている PHP メソッドが見つからなかったので、CBC.pm で見つけたデコードの独自の PHP バージョンを次に示します。キーと iv を抽出し、mcrypt に作業を完了させます。

function cred_decrypt($input, $password)
{
  /************************* Inspired by Crypt/CBC.pm *******************************/
  $input = pack('H*', $input);
  if (substr($input, 0, 8) != 'Salted__') {
    die("Invalid hash header, expected 'Salted__', found '".substr($input, 0, 8)."'");
  }
  $salt   = substr($input, 8, 8);
  $input  = substr($input, 16);

  $key_len  = 32;
  $iv_len   = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC);

  $data = '';
  $d    = '';
  while (strlen($data) < $key_len+$iv_len) {
    $d = md5($d . $password . $salt, TRUE);
    $data .= $d;
  }
  $key  = substr($data, 0, $key_len);
  $iv   = substr($data, $key_len, $iv_len);
  /**********************************************************************************/

  return rtrim(mcrypt_decrypt(MCRYPT_RIJNDAEL_128, $key, $input, MCRYPT_MODE_CBC, $iv), "\0\n\3");
}

注:私の場合、rtrimが必要でした。終了する改行があればそれを食べる可能性があります。

于 2013-07-03T13:41:03.250 に答える
0

それもうまくいきませんでした。PerlのCBC::Cryptは、PHPのmcrypt関数とはかなり異なる動作をするように感じます。PHPディレクトリでmcrypt関数のソースコードを見つけて比較しようとしていますが、まだ運がありません。

于 2010-04-13T15:48:16.250 に答える