2010-04-09 3 views
1

Perl Crypt :: CBC (Rijndael, cbc)로 암호화 된 암호화 된 문자열이 있습니다. 원본 평문은 Crypt :: CBC의 encrypt_hex() 메소드로 암호화되었습니다.Perl CBC로 암호화하고 PHP mcrypt로 해독

$encrypted_string = '52616e646f6d49567b2c89810ceddbe8d182c23ba5f6562a418e318b803a370ea25a6a8cbfe82bc6362f790821dce8441a790a7d25d3d9ea29f86e6685d0796d'; 

사용 된 32 자 키가 있습니다.

mcrypt가 성공적으로 PHP로 컴파일되었지만 PHP에서 문자열의 암호를 해독하려고 애 쓰고 있습니다. 나는 계속 변덕스러워지고있다.

압축을 풀면 ('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; 

어떤 도움이 올바른 방향으로 포인터는 크게 감상 할 수있다. 추가 정보를 제공해야하는지 알려주세요.

답변

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; 
0

중 하나가 작동하지 않았다. 나는 Perl의 CBC :: Crypt가 PHP의 mcrypt 기능과 많이 다른 점을 느끼고있다. 필자는 필자의 PHP 디렉토리에서 mcrypt 함수의 소스 코드를 찾아 보려고 노력했지만 아직 행운은 없습니다.

1

이 답변은 randomized 모드가 아닌 Crypt :: CBC의 소금에 절인 모드에 대한 답변입니다. 그러나이 솔루션은 해결책을 검색 할 때 다른 페이지도 찾을 수 있습니다.

이 펄 코드를 사용하여

:

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

(또는 소금, 기본적으로이 값이 헤더없이) 펄에서 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이 필요하다. 줄 바꿈 줄이 있다면 먹을 수도있다.

관련 문제