简体   繁体   中英

php decrypt string with MCRYPT_RIJNDAEL_256

<?php
function encrypt ($key,$iv,$str)
{     
  $block=mcrypt_get_block_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_CBC);
  $padding=$block-(strlen($str) % $block);
  $str.=str_repeat(chr($padding), $padding);  
  $encryptxt=mcrypt_encrypt(MCRYPT_RIJNDAEL_256,$key,$str,MCRYPT_MODE_CBC,$iv);  
  $encryptxt64=base64_encode($encryptxt);
  return $encryptxt64;
}
function decrypt ($key,$iv,$str)
{     
  $block=mcrypt_get_block_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_CBC);
  $padding=$block-(strlen($str) % $block);
  $str.=str_repeat(chr($padding), $padding);  
  $decryptxt=mcrypt_decrypt(MCRYPT_RIJNDAEL_256,$key,$str,MCRYPT_MODE_CBC,$iv);  
  $decryptxt64=base64_decode($decryptxt);
  return $decryptxt64;
}
echo encrypt("1234567890123456","12345678901234561234567890123456","test")."\n<br/>";
echo decrypt("1234567890123456","12345678901234561234567890123456","xHqKvRQ6FXehOGGMrKoek04146M2l9bv1ScP6C1qCyg=")."\n<br/>";
?>

I found this way can encrypt string,works fine,but when I tried to decrypt a string,above codes does not working. the decrypt output likes

S '= ɚ?

Does anybody know how to fix the decrypt part?Thanks in advance!

as I stated in the comments This is what you have

  //encrypt
 $encryptxt=mcrypt_encrypt(MCRYPT_RIJNDAEL_256,$key,$str,MCRYPT_MODE_CBC,$iv);  
  $encryptxt64=base64_encode($encryptxt);

 //decrypt 
   $decryptxt=mcrypt_decrypt(MCRYPT_RIJNDAEL_256,$key,$str,MCRYPT_MODE_CBC,$iv);  
  $decryptxt64=base64_decode($decryptxt);
  1. encrypt
  2. base64 encode
  3. decrypt
  4. base64 decode

it should be FILO ( first in last out )

  1. encrypt
  2. base64 encode
  3. base64 decode
  4. decrypt

That way you are decrypting the output of encrypt and not the base64 encoded output,

Like So:

$encryptxt=mcrypt_encrypt(MCRYPT_RIJNDAEL_256,$key,$str,MCRYPT_MODE_CBC,$iv);  
  $encryptxt64=base64_encode($encryptxt);

//decrypt 
 $decryptxt64=base64_decode($str);
$decryptxt=mcrypt_decrypt(MCRYPT_RIJNDAEL_256,$key,$decryptxt64,MCRYPT_MODE_CBC,$iv);  

As a note MCRYPT_RIJNDAEL_256 is NOT AES 256, for that you need MCRYPT_RIJNDAEL_128 with a 32byte key, So in some regards 128 is better, ( 128 being a smaller block cypher )

One other thing I would suggest doing is taking a md5 hash of the input string and then preending that to the input string, before encryption. This is so that when you unecrypt it you can substr the first 32 characters and use that to check the input. Basically you need to know the input string in order to see if it was decrypted. But, by hashing it and then comparing like this you no longer need to know that to check that it works.

So all together ( haven't tested it but should get you close )

function encrypt ($key,$iv,$str)
{     
  $block=mcrypt_get_block_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_CBC);
  $padding=$block-(strlen($str) % $block);
  $str.=str_repeat(chr($padding), $padding);  

  ///prepend a md5 hash of the plain text input before encrypting it ( so we can check it later )
  $str = md5( $str ) . $str;

    $encryptxt=mcrypt_encrypt(MCRYPT_RIJNDAEL_256,$key,$str,MCRYPT_MODE_CBC,$iv);  
  $encryptxt64=base64_encode($encryptxt);
  return $encryptxt64;
}
function decrypt ($key,$iv,$str)
{     
  $block=mcrypt_get_block_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_CBC);
  $padding=$block-(strlen($str) % $block);
  $str.=str_repeat(chr($padding), $padding);  

  $decryptxt64=base64_decode($str);
  $decryptxt=mcrypt_decrypt(MCRYPT_RIJNDAEL_256,$key,$decryptxt64,MCRYPT_MODE_CBC,$iv);  

   ///Separate the md5 hash from the other text, and then hash the other text and compare to the hash we included when encrypting  if they are = it all worked.
  /// it is perfectly safe to use md5 here because it will be part of what we encrypt, and not accessible until it is decrypted. 
 ///it's sole purpose is to give us 2 things we can compare to check that the decryption worked
  $hash = substr( $decryptxt, 0, 32); //find first 32 characters (md5 output is always 32 characters long )
  $decryptxt = substr($decryptxt, 33); //find everything after the fist 32
  if( $hash != md5($decryptxt) ){
        die( 'fail' ); /// or some other error
  }


  return $decryptxt64;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM