Syphon Posted March 25, 2008 Share Posted March 25, 2008 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. Quote Link to comment Share on other sites More sharing options...
PFMaBiSmAd Posted March 25, 2008 Share Posted March 25, 2008 It is very likely that an error is occurring. Add the following two lines after your first opening <?php tag - ini_set ("display_errors", "1"); error_reporting(E_ALL); Quote Link to comment Share on other sites More sharing options...
Laxidasical Posted March 25, 2008 Share Posted March 25, 2008 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! Quote Link to comment Share on other sites More sharing options...
Syphon Posted March 25, 2008 Author Share Posted March 25, 2008 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. Quote Link to comment Share on other sites More sharing options...
Laxidasical Posted March 25, 2008 Share Posted March 25, 2008 Try changing your mode to cbc: $td = mcrypt_module_open('tripledes', '', 'cbc', ''); instead of... $td = mcrypt_module_open('tripledes', '', 'cfb', ''); Quote Link to comment Share on other sites More sharing options...
Syphon Posted March 25, 2008 Author Share Posted March 25, 2008 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. Quote Link to comment Share on other sites More sharing options...
Laxidasical Posted March 25, 2008 Share Posted March 25, 2008 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'] Quote Link to comment Share on other sites More sharing options...
Syphon Posted March 25, 2008 Author Share Posted March 25, 2008 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. Quote Link to comment Share on other sites More sharing options...
Laxidasical Posted March 25, 2008 Share Posted March 25, 2008 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!!! Quote Link to comment Share on other sites More sharing options...
Laxidasical Posted March 25, 2008 Share Posted March 25, 2008 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... Quote Link to comment Share on other sites More sharing options...
Syphon Posted March 25, 2008 Author Share Posted March 25, 2008 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. Quote Link to comment Share on other sites More sharing options...
Laxidasical Posted March 25, 2008 Share Posted March 25, 2008 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... Quote Link to comment Share on other sites More sharing options...
Syphon Posted March 25, 2008 Author Share Posted March 25, 2008 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. Quote Link to comment Share on other sites More sharing options...
Laxidasical Posted March 25, 2008 Share Posted March 25, 2008 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); Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.