2010-04-09 4 views
1

J'ai une chaîne cryptée qui a été cryptée avec Perl Crypt :: CBC (Rijndael, cbc). Le texte en clair original a été chiffré avec la méthode encrypt_hex() de Crypt :: CBC.Cryptage avec Perl CBC et décryptage avec PHP mcrypt

$encrypted_string = '52616e646f6d49567b2c89810ceddbe8d182c23ba5f6562a418e318b803a370ea25a6a8cbfe82bc6362f790821dce8441a790a7d25d3d9ea29f86e6685d0796d'; 

J'ai la clé de 32 caractères qui a été utilisée. Mcrypt est compilé avec succès en PHP, mais j'ai du mal à décrypter la chaîne en PHP. Je continue à avoir du charabia.

Si je déballe ('H *', $ encrypted_string), je vois 'RandomIV' suivi de ce qui ressemble à binaire.

Je n'arrive pas à extraire correctement le message IV et à séparer le message chiffré réel. Je sais que je ne fournis pas mes informations, mais je ne sais pas par où commencer.

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

Toute aide, pointeurs dans la bonne direction, serait grandement appréciée. Faites-moi savoir si je dois fournir plus d'informations.

Répondre

2

Je pense que la IV à utiliser est juste générée aléatoirement par CBC :: Crypt. Si j'ai raison et que je lis correctement le document, ce sont les 32 premiers octets de la chaîne décompressée.

essayer avec la bonne clé:

$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

qui ne fonctionnait pas non plus. J'ai le sentiment que CBC :: Crypt de Perl fait les choses différemment des fonctions mcrypt de PHP. J'ai essayé de trouver le code source pour les fonctions mcrypt dans mon répertoire PHP pour les comparer, mais pas de chance pour le moment.

1

Cette réponse est pour le mode salé de Crypt :: CBC, pas le mode randomIV, mais c'est la page sur laquelle j'ai fini lorsque je cherchais une solution.

Lorsque vous utilisez ce code 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); 

(ou même sans sel et en-tête qui ont ces valeurs par défaut) Perl crée un hachage qui est censé être conforme à OpenSSL. Je n'ai trouvé aucune méthode PHP qui sache lire ceci, donc voici ma propre version PHP du décodage trouvé dans CBC.pm. J'extrais la clé et iv, puis je laisse mcrypt terminer le travail.

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"); 
} 

Note: l'rtrim était nécessaire dans mon cas, il pourrait manger la fin des nouvelles lignes le cas échéant.

Questions connexes