Jump to content

Using Mcrypt


Syphon

Recommended Posts

I've followed the tutorial located here for encryption. Using the same encryption method and algorithm, my output is drastically different. The tutorial seems to have a very URL friendly result, which is what I'm looking for.

 

Secondly, each time my "super secret string" is encrypted, the output is always the same. Why isn't the encrypted result different? This is a bit of a security issue.

 

Current environment is set up on a Windows platform with Apache. Live environment is Unix based.

 

Thanks in advance.

Link to comment
Share on other sites

Hey Syphon,

 

The key is encrypted via md5, which will ALWAYS output the same result when given the same date string.  This is a good thing!  Otherwise your script would try to encode/decode your data with a different key every time and you'd get garbage back.  Even though your key is encrypted, it is still "super secret"!!!  To keep it a secret, a lot of people save their mcrypt script above the route directory and include it from there.  Personally, if your script resides on a server that is not your own, someone somewhere at your host has access.  I prefer to encode files that contain sensitive information like this.

 

Now the output data is a different story.  You should be getting a different encrypted string every time, even if you are encrypting the same exact data!  That is why you need to pass the initiation value (iv) every time, it's sort of like a primer for that data's encryption.

 

I'm dealing with an mcrypt issue myself right now.  I've been going crazy trying to figure it out.  Hopefully passing along a little of what I've learned along the way will help you!  :)

Link to comment
Share on other sites

Added the line like you suggested but no errors show up. Check out the code.

 

ini_set ("display_errors", "1");
error_reporting(E_ALL);
$td = mcrypt_module_open('tripledes', '', 'cfb', '');
$keySize = mcrypt_enc_get_key_size($td);
$initializationVector = "CyJ^54%!";
$Key = substr('very secret key', 0, $keySize);

//Strange little unexplained bug. The Keysize is 24, but when using tripledes an error is thrown stating that the required key length is 8
//$Key = substr(md5('very secret key'), 0, $keySize);
$Key = substr(md5('very secret key'), 0, ;

/* Intialize encryption */
    mcrypt_generic_init($td, $Key, $initializationVector);
$encrypted = mcrypt_generic($td, 'This is some very important data');

/* Terminate encryption handler */
    mcrypt_generic_deinit($td);

 

Nothing complicated, but it should be different each time, like Laxidasical stated. As for the MD5 encrypting, that's just for testing right now. The real key will be retrieved with a more secure method.

 

UPDATE: Normally I would be using the mcrypt_create_iv() method, but because of the little bug mentioned above, the IV turns out to be invalid. Also the constant MCRYPT_RAND does not work (or any of the other constants for that matter) for me so I've resorted to using a constant as an IV.

Link to comment
Share on other sites

I've tried ecb, cbc, cfb, ofb, and nofb. The encrypted result is still the same every time. It almost seems like mcrypt is using the same algorithm to encrypt every time, regardless of what I put. Every encryption method and mode yields a suspiciously similar result. Not that I'm an expert in encryption, but I'd expect some sort of pattern that is different than the last encryption method.

Link to comment
Share on other sites

That is because you are using the same iv every time.  If the key and iv are always the same, you'll always get the same result.  The first issue to solve is why mcrypt_create_iv() isn't working.

 

What version of PHP are you running???  If it's lower that 4.2, then this applies:

 

Note: When using MCRYPT_RAND' date=' remember to call srand() before mcrypt_create_iv() to initialize the random number generator; it is not seeded automatically like rand() is.[/quote']
Link to comment
Share on other sites

That is because you are using the same iv every time.  If the key and iv are always the same, you'll always get the same result.  The first issue to solve is why mcrypt_create_iv() isn't working.

 

What version of PHP are you running???  If it's lower that 4.2, then this applies:

 

Note: When using MCRYPT_RAND' date=' remember to call srand() before mcrypt_create_iv() to initialize the random number generator; it is not seeded automatically like rand() is.[/quote']

 

I'm using 5.2.1. When I try to use mcrypt_create_iv() this message is displayed.

 

mcrypt_generic_init() [function.mcrypt-generic-init]: Iv size incorrect; supplied length: 24, needed: 8

 

I can't understand why that warning would show up if I'm using the function mcrypt_enc_get_key_size() to determine the key size. At any rate, this is what the code looks like using mcrypt_create_iv()

 

    //srand();
    $td = mcrypt_module_open('tripledes', '', 'cbc', '');
    $keySize = mcrypt_enc_get_key_size($td);
    echo $keySize; //outputs 24     
    $initializationVector = mcrypt_create_iv($keySize, MCRYPT_RAND);

 

As for using the same IV, if I don't use the same IV to decrypt then the message doesn't decrypt properly. Depending on the mode used, the whole message or the beginning part still looks encrypted.

Link to comment
Share on other sites

You need to get the iv size when calling mcrypt_create_iv(), not the key size. Thy this...

 

$initializationVector = mcrypt_create_iv(mcrypt_enc_get_iv_size($td), MCRYPT_RAND);

 

You won't need the $keySize variable any more unless you use it some place else as well. If you want to pull the mcrypt_enc_get_iv_size() function out, you can do something like...

 

$ivSize = mcrypt_enc_get_iv_size($td);
$initializationVector = mcrypt_create_iv($ivSize, MCRYPT_RAND);

 

<b>UPDATE:</b> I see you do use $keySize other places, so DON'T get rid of it!!!

Link to comment
Share on other sites

Oh yeah, as far as the last part of your post...

 

You have to use the same iv that you encrypted with.  When you get the random iv part working (which hopefully my above post will fix), you will need to pass that random iv back with your encrypted data in order to decrypt it correctly.  This has to be done every time!

 

What I did was pass an array of variables to my mcrypt script, looped through each, encrypted it and added it to second array, added the iv as an element of the second array, then passed back that array using the same array keys with corresponding encrypted strings.  This prevents me from having to store x different ivs if I have x different variables.  Let me know if that makes sense the way I typed it.  If not, I'll explain in detail...

Link to comment
Share on other sites

It seems that this code is invalid

$ivSize = mcrypt_enc_get_iv_size($td);
$initializationVector = mcrypt_create_iv($ivSize, MCRYPT_RAND);

 

If just won't work unless the code looks like this:

$initializationVector = mcrypt_create_iv(mcrypt_enc_get_iv_size($td), MCRYPT_RAND);

 

Although this fixes one issue, it still doesn't create a different encryption result each time the page is hit.

 

I understand what you mean with using an array to store the result and vector in; however, wouldn't this require that I put both my encryption result and vector into the querystring?

 

UPDATE: If the vector is always the same, wouldn't that mean that MCRYPT_RAND isn't working, or always providing the same random number? Tried with srand() and the vector still is the same.

Link to comment
Share on other sites

Hmmm...that's very odd! echo $initializationVector and see if it is different every time. If not, that is the issue. Also, did you remove this line:

 

$initializationVector = "CyJ^54%!";

 

Yes, you will have to store both the encryption result and iv somewhere (session, database, etc), then return them both to your mcrypt function in order to decrypt properly.

 

UPDATE: Also, did you change the mode to cbc, or leave it as it was???  I don't know which, but some modes don't return different results.  I know cbc will though...

Link to comment
Share on other sites

As is stands, this is everything that's running

srand();    
    $td = mcrypt_module_open('tripledes', '', 'cbc', '');
    $Key = substr(md5('very secret key'), 0, mcrypt_enc_get_iv_size($td));     
    $initializationVector = mcrypt_create_iv(mcrypt_enc_get_iv_size($td), MCRYPT_RAND);
    
    echo "Initialization Vector:".$initializationVector."<br />";        
                             
    mcrypt_generic_init($td, $Key, $initializationVector);

    /* Encrypt data */
    $encrypted = mcrypt_generic($td, 'This is some very important data');
    echo "Encrypted: ".$encrypted."<br />";
    $encoded = urlencode($encrypted);
    echo "URL Encoded: ".$encoded."<br />";
    echo "URL Decoded: ".urldecode($encoded)."<br />";
                                        
    mcrypt_generic_deinit($td);                                                     
    mcrypt_generic_init($td, $Key, $initializationVector);
                                  
    $decrypted = mdecrypt_generic($td, $encrypted); 
    mcrypt_generic_deinit($td);
    mcrypt_module_close($td);
    
    echo "Decrypted: ".$decrypted."<br />";
    
    //Do everything again to see if it decrypts properly
    $td = mcrypt_module_open('tripledes', '', 'cbc', '');
    $initializationVector = mcrypt_create_iv(mcrypt_enc_get_iv_size($td), MCRYPT_RAND);
    mcrypt_generic_init($td, $Key, $initializationVector);
    $decrypted = mdecrypt_generic($td, $encrypted);
    mcrypt_generic_deinit($td);
    mcrypt_module_close($td);
    
    echo "2nd Decryption: ".$decrypted."<br />";
    echo "Rand: ".MCRYPT_RAND;

 

It seems that MCRYPT_RAND is always staying the same. This should probably be fixed first, but that's a predefined constant. I remember reading on another forum that MCRYPT_RAND wasn't working in windows and the author recommended their own function to create a vector.

Link to comment
Share on other sites

I'm working on Windows (Vista) as well for development, and MCRYPT_RAND is working.  I'm using IIS 7 though, and PHP 5.2.4.  I've read that quite a few people are having the same problem as you on Windows machines.

 

If what I suggested in my last post didn't work, I was going to suggest creating your own iv.  It doesn't have to be created by mcrypt_create_iv(), it just has to be random (and in your case 8 characters long).  Keep in mind, when you move it to the UNIX machine, it may expect an iv longer or shorter than 8 characters.  Something like this...

 

function iv ($size = '8')
{
    $iv = '';

    for($i = 0; $i < $size; $i++)
    {
        $iv .= chr(rand(0,255));
    }

    return $iv;
}

 

Also, one slight thing...

 

$Key = substr(md5('very secret key'), 0, mcrypt_enc_get_iv_size($td));

 

should be...

 

$Key = substr(md5('very secret key'), 0, mcrypt_enc_get_key_size($td));

 

mcrypt_enc_get_iv_size() should only be used on:

 

$initializationVector = mcrypt_create_iv(mcrypt_enc_get_iv_size($td), MCRYPT_RAND);

Link to comment
Share on other sites

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.