Question

I know there are already a million posts on PHP's mcrypt_decrypt, but I couldnt' find one that had the same results as mine. I have a pair of simple encrypt/decrypt functions that I'd like to use to perform a two-way encryption on data. The strange thing is, for about 4% of any random string that I feed into the functions, it will not decrypt successfully. If I create a "for loop" from 0 to 9999, for example, and encrypt and decrypt the string version of those numbers, the same values will fail each time, and those values depend upon the key that I pass into the function. I can pass any key, and although the specific values that fail will change, the percentage of values that fail will remain roughly constant.

I have tried ECB mode without an IV parameter, and I've tried CBC mode with an IV parameter, and it yields the same results.

Here is my encrypt function in ECB mode:

function mc_encrypt($string, $mc_key) {
    $passcrypt = trim(mcrypt_encrypt(MCRYPT_RIJNDAEL_256, $mc_key, trim($string), MCRYPT_MODE_ECB));
    $encode = base64_encode($passcrypt);

    return $encode;
}

And here is my decrypt function in ECB mode:

function mc_decrypt($string, $mc_key) {
    $decoded = base64_decode($string);
    $decrypted = trim(mcrypt_decrypt(MCRYPT_RIJNDAEL_256, $mc_key, trim($decoded), MCRYPT_MODE_ECB));

    return $decrypted;
}

The CBC mode version was the same, except it used the mcrypt_create_iv() function to create an IV in the encryption, and passed it in as a parameter in the decryption.

Using these functions on my server with 'abc' as a test encryption key, if I run from 0 to 300, the following values won't decrypt properly:

4, 6, 70, 145, 151, 176, 237, 254, 275

If I change my encryption key to something else, it will shift which values return properly, but it won't change the frequency with which the values come back.

Any suggestions???

Thanks in advance!

Was it helpful?

Solution

I just took two trim() calls out of your code, and it works. Basically, mcrypt_encrypt may return an answer with trailing null bytes (\0), need to keep those. Also, don't trim the $decoded parameter to mcrypt_decrypt for the same reason. And when trimming the response from mcrypt_decrypt, only use rtrim.

function mc_encrypt($string, $mc_key) {
    $passcrypt = mcrypt_encrypt(MCRYPT_RIJNDAEL_256, $mc_key, trim($string), MCRYPT_MODE_ECB);
    $encode = base64_encode($passcrypt);

    return $encode;
}

function mc_decrypt($string, $mc_key) {
    $decoded = base64_decode($string);
    $decrypted = rtrim(mcrypt_decrypt(MCRYPT_RIJNDAEL_256, $mc_key, $decoded, MCRYPT_MODE_ECB));

    return $decrypted;
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top