Problem encrypting/encoding URL variable

2019-07-29 02:15发布

I have a class that takes a string in this format:

000067000000000012620060324b38e2cab3353

, encrypts the string then appends it as a get variable in a URL.

The class that does the encryption has a function that looks like this:

private function _code_encryption($enc_type,$a_string){
    $iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_CBC); 
    $iv = mcrypt_create_iv($iv_size, MCRYPT_RAND);                          

    if($enc_type == self::ENCRYPT_STRING){
       //encrypt then return base64 encoded
       $encrypted = mcrypt_encrypt(MCRYPT_RIJNDAEL_256, self::AUTH_ENCRYPTION_KEY, $a_string, MCRYPT_MODE_CBC, $iv);
       return base64_encode($encrypted);
    }elseif($enc_type == self::DECRYPT_STRING){
       $decrypted = mcrypt_decrypt(MCRYPT_RIJNDAEL_256, self::AUTH_ENCRYPTION_KEY, base64_decode($a_string), MCRYPT_MODE_CBC, $iv);
        return trim($decrypted);
    }
}

When the string is encrypted I urlencode the value and add it to the url like the url looks like "https://secure.mysite.com/index.php?action=someaction&transfer_code=XXXXX where XXXX is the urlencoded encrypted string.

Now, when the url is parsed and processed the value of $_GET['transfer_code'] is getting passed into the above _code_encryption function but is not returning the correctly decrypted value and instead returns garbled characters my browser doesn't render. Is there a requirement for the length of the key I use for encryption/decryption? I tried something like

$key = hash('sha256',self::AUTH_ENCRYPTION_KEY,true);

but that didn't work either...

Also, I am not urldecoding the $_GET['transfer_code'] variable because the php man pages state that get vars are already urlencoded...

Should I be UTF-8 encoding the alphanumeric string BEFORE encryption/base64_encoding, or will that even make any difference?

1条回答
你好瞎i
2楼-- · 2019-07-29 02:31

You use a random IV to encrypt, and the a different random IV to decrypt. The decrypted string will never ever match the original. To properly decrypt the original string you must use the same IV that was used during encryption. Usually this is achieved by prepending the IV used to the encrypted string. At decryption time you must first extract the IV from the value, initialize the key with this value, then decrypt the rest usign the properly initialized key.

I don't have a parser to validate this but it should be something like:

private function _code_encryption($enc_type,$a_string){
 $iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_CBC); 
 if($enc_type == self::ENCRYPT_STRING){
  //encrypt then return base64 encoded
  $iv = mcrypt_create_iv($iv_size, MCRYPT_RAND);
  $encrypted = mcrypt_encrypt(MCRYPT_RIJNDAEL_256, self::AUTH_ENCRYPTION_KEY, $a_string, MCRYPT_MODE_CBC, $iv);
  return base64_encode($iv.$encrypted);
 } elseif ($enc_type == self::DECRYPT_STRING){
  $decoded = base64_decode($a_string);
  $iv = substr($decoded,0,$iv_size);
  $cipher = substr($decoded,$iv_size);
  $decrypted = mcrypt_decrypt(MCRYPT_RIJNDAEL_256, self::AUTH_ENCRYPTION_KEY, $cipher, MCRYPT_MODE_CBC, $iv);
  return trim($decrypted);
 }
}
查看更多
登录 后发表回答