PFMaBiSmAd Posted June 27, 2008 Share Posted June 27, 2008 First of all, two-way encryption/decryption is not the same as a one-way hash. Getting this to work is not a matter of finding the right class or right code it is a matter of finding why your code and data is not working. I created a database with a blob column and tested your class code and it works. So, something that php is doing (such as the magic_quotes_runtime setting adding escape characters to the data when it comes out of the database) or something your code is doing is causing the problem. For all we know, your code is doing an md5 on the data (since some of this seems to be left over from a password function.) We really need to see your code to be able to help. Have you echoed out the various values to make sure of what they contain and have you compared these with what is in the database? Does the string you get out of the database have \ in it before several of the characters? The string you insert into the database, the string in the database, and the string you select out of the database should all be identical. The class code you posted has a rtrim() in the decrypt function left over from when it was a password function. I recommend removing that (it would have no effect on a true CC number unless there were trailing trim-able characters, which your validation code should have dealt with long before they were encrypted.) The code Jabop posted has an additional trim() function added to the encoding. This can break the process because there could be leading and trailing trim-able characters. Link to comment https://forums.phpfreaks.com/topic/112225-solved-mcrypt/page/2/#findComment-576234 Share on other sites More sharing options...
Jabop Posted June 27, 2008 Share Posted June 27, 2008 This is just plain ugly, and quite redundant. Simply using a random salt, and randomly mixing it in with a hash is more than enough to make it unfeasible to brute-force, and also protects it from any existing table-based attacks. That will be really hard to return the CC numbers at all when you do that - and I think he needs to store the numbers for records. It'd be easier to just encrypt the numbers and decrypt them when needed Link to comment https://forums.phpfreaks.com/topic/112225-solved-mcrypt/page/2/#findComment-576235 Share on other sites More sharing options...
Jabop Posted June 27, 2008 Share Posted June 27, 2008 The code Jabop posted as an additional trim() function added to the encoding. This can break the process because there could be leading and trailing trim-able characters. Why would you use whitespace in a credit card number? Link to comment https://forums.phpfreaks.com/topic/112225-solved-mcrypt/page/2/#findComment-576237 Share on other sites More sharing options...
PFMaBiSmAd Posted June 27, 2008 Share Posted June 27, 2008 You are trimming the encrypted output where it is being returned to the calling function. Edit: The encrypted output can contain any 0-255 value. Trim removes several of these values - " " (ASCII 32 (0x20)), an ordinary space. "\t" (ASCII 9 (0x09)), a tab. "\n" (ASCII 10 (0x0A)), a new line (line feed). "\r" (ASCII 13 (0x0D)), a carriage return. "\0" (ASCII 0 (0x00)), the NUL-byte. "\x0B" (ASCII 11 (0x0B)), a vertical tab. Link to comment https://forums.phpfreaks.com/topic/112225-solved-mcrypt/page/2/#findComment-576238 Share on other sites More sharing options...
Jabop Posted June 27, 2008 Share Posted June 27, 2008 Right, that is what trim does. In a credit card number, only numbers are allowed (obv), so I put trim in there for his sake. Link to comment https://forums.phpfreaks.com/topic/112225-solved-mcrypt/page/2/#findComment-576248 Share on other sites More sharing options...
br0ken Posted June 27, 2008 Author Share Posted June 27, 2008 Here is the code I've been using to test the encryption functions. First I select the credit card number (cnumber) and then encrypt it and then decrypt it. These values are stored in cnumbenc and cnumbdec. After this has been done for all of the numbers I display the resulting table. The commented out line loads the encrypted value from the database, decrypts it then stores it in cnumbenc. $db = openDB(); $rs = queryDB("SELECT id, cnumber FROM tblCard LIMIT 100"); $row = 0; while(getrowRS($rs)) { $id = getvalueRS($rs, $row, "id"); $card = getvalueRS($rs, $row, "cnumber"); $enc = xEncrypt($card, mykey()); $dec = xDecrypt($enc, mykey()); queryDB("UPDATE tblCard SET cnumbenc = '".mysql_real_escape_string($enc)."', cnumbdec = '".mysql_real_escape_string($dec)."' WHERE id = $id"); # $dec = xDecrypt(queryDBval("SELECT cnumbenc FROM tblCard WHERE id = $id"), mykey()); # queryDB("UPDATE tblCard SET cnumbdec = '".input($dec, 60)."' WHERE id = $id"); ++$row; } printRS(queryDB("SELECT id, cnumber, cnumbenc, cnumbdec FROM tblCard LIMIT 100")); Link to comment https://forums.phpfreaks.com/topic/112225-solved-mcrypt/page/2/#findComment-576251 Share on other sites More sharing options...
discomatt Posted June 27, 2008 Share Posted June 27, 2008 Right, that is what trim does. In a credit card number, only numbers are allowed (obv), so I put trim in there for his sake. Yes but you're trimming the ENCRYPTED STRING! Which you should not do, as it can strip important leading and trailing bits. It's a binary value, not ASCII. Trimming is BAD That will be really hard to return the CC numbers at all when you do that - and I think he needs to store the numbers for records. It'd be easier to just encrypt the numbers and decrypt them when needed I realize this, i was simply telling him a better way to hash. And it's not really hard - it's impossible without brute forcing. Why you'd do that to your own data, I'm not entirely sure. Link to comment https://forums.phpfreaks.com/topic/112225-solved-mcrypt/page/2/#findComment-576253 Share on other sites More sharing options...
PFMaBiSmAd Posted June 27, 2008 Share Posted June 27, 2008 @Jabop, I think you need to read the code you posted. In the encrypt function is this line - return trim($CryptStr); That will remove any leading or trailing trim-able characters from the encrypted function, destroying the encrypted cypher. Link to comment https://forums.phpfreaks.com/topic/112225-solved-mcrypt/page/2/#findComment-576257 Share on other sites More sharing options...
discomatt Posted June 27, 2008 Share Posted June 27, 2008 @ broken So the value is first stored in the DB in plain text, then encrypted and re-stored? This seems inefficient. Anyways, here's code that's worked for me on my test system. <?php define("ENCKEY", "SomeRandomKey"); function enc($str) { $size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB); $iv = mcrypt_create_iv($size, MCRYPT_RAND); return mcrypt_encrypt(MCRYPT_RIJNDAEL_256, ENCKEY, $str, MCRYPT_MODE_ECB, $iv); } function dec ($str) { $size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB); $iv = mcrypt_create_iv($size, MCRYPT_RAND); return trim( mcrypt_decrypt(MCRYPT_RIJNDAEL_256, ENCKEY, $str, MCRYPT_MODE_ECB, $iv) ); } /* table data CREATE TABLE `test_crypt` ( `data` BLOB NOT NULL ) ENGINE = innodb; */ echo <<<HEREDOC <form method="post" action=""> <input type="text" name="str"><br /> <input type="submit" value="Submit"><br /> <br /> HEREDOC; mysql_connect('localhost', 'root', ''); mysql_select_db('test'); if ( $_POST['str'] ) if ( !mysql_query("INSERT INTO `test_crypt` SET `data` = '" . mysql_real_escape_string( enc($_POST['str']) ) . "'" ) ) echo 'Your query sucks!<br />' . mysql_error() . '<br />'; $r = mysql_query( 'SELECT `data` FROM `test_crypt`' ); if ( !$r ) echo 'Your second query sucks!<br />' . mysql_error() . '<br />'; else while ( $d = mysql_fetch_assoc($r) ) { echo '<br />Encrypted string: ' . $d['data']; echo '<br />Decrypted string: ' . dec( $d['data'] ); echo '<br />'; } ?> Returns something like this (linebreaks added for readability): <form method="post" action=""> <input type="text" name="str"><br /> <input type="submit" value="Submit"><br /> <br /><br /> Encrypted string: F „³¾å0õé9òæ|:K¸™AÿH/M=7/š <br /> Decrypted string: testing <br /><br /> Encrypted string: M1ŠP!®ÄÆ;ß"ˆÞúüyóð±î¸+zÃx‡ <br /> Decrypted string: zomgS! <br /> Link to comment https://forums.phpfreaks.com/topic/112225-solved-mcrypt/page/2/#findComment-576265 Share on other sites More sharing options...
br0ken Posted June 27, 2008 Author Share Posted June 27, 2008 @ broken So the value is first stored in the DB in plain text, then encrypted and re-stored? This seems inefficient. Anyways, here's code that's worked for me on my test system. No, the credit card numbers are in the database currently as samples. I'm extracting that number and entering the decrypted version into the database and then extracting it and attempting to decrypt it. Once I've got it working I'll integrate it into my actual system. Thanks for the sample code, I shall give it a try now! Link to comment https://forums.phpfreaks.com/topic/112225-solved-mcrypt/page/2/#findComment-576270 Share on other sites More sharing options...
br0ken Posted June 27, 2008 Author Share Posted June 27, 2008 This worked perfectly! Thank you so much everybody for helping me out. One more question I have... With the decrypted string being binary information, if it's saved in a ascii file backup, could it still be restored or would this corrupt the data? Link to comment https://forums.phpfreaks.com/topic/112225-solved-mcrypt/page/2/#findComment-576281 Share on other sites More sharing options...
discomatt Posted June 27, 2008 Share Posted June 27, 2008 The decrypted string is ASCII, the encrypted string is binary. Storing encrypted strings in a text file may be an issue, as there's no 'safe' way to separate the values... as you can see in my example, the encrypted string for 'testing' created a linebreak when displayed in ascii... A way to do it might be to store it 'line-by-line', starting the line with the length of the encrypted string in bits, then a known character, say a hyphen, then the encrypted string... That way, when you parse it, you can create a function that will read the first line, grab the numeric length, skip the known character, then read until the length is up, then look for a linebreak, and repeat. Link to comment https://forums.phpfreaks.com/topic/112225-solved-mcrypt/page/2/#findComment-576296 Share on other sites More sharing options...
PFMaBiSmAd Posted June 27, 2008 Share Posted June 27, 2008 Define: "saved in a ascii file backup" A standard .sql dump saves binary fields in hex. The following is from the test db I made for this thread - INSERT INTO `cc` (`id`,`cc`) VALUES (0,0x1D7B95F18CED5D336B75EB4864529C8C14C7279EDC68203D90F73026ED6C193DEBE66608CEC557E868D68E83265E528F1CA8B4B414620762069E9B1BB3AF6BD9); Link to comment https://forums.phpfreaks.com/topic/112225-solved-mcrypt/page/2/#findComment-576321 Share on other sites More sharing options...
discomatt Posted June 27, 2008 Share Posted June 27, 2008 Mmm.. and you can use the bin2hex() function to convert your binary strings to hex Link to comment https://forums.phpfreaks.com/topic/112225-solved-mcrypt/page/2/#findComment-576337 Share on other sites More sharing options...
br0ken Posted June 27, 2008 Author Share Posted June 27, 2008 Unfortunately our server wont allow us to run a sql dump so I've written my own script to perform the same task. I've got the encrypted credit card number to store in a TEXT field and it works ok. Because it's in a text field, would it be ok in an ascii file? Also, bin2hex is good but is there a function to reverse this? I know hex2bin doesn't exist but is there an equivilant? Link to comment https://forums.phpfreaks.com/topic/112225-solved-mcrypt/page/2/#findComment-576341 Share on other sites More sharing options...
discomatt Posted June 27, 2008 Share Posted June 27, 2008 Check the bin2hex user comments. http://php.net/manual/en/function.bin2hex.php Link to comment https://forums.phpfreaks.com/topic/112225-solved-mcrypt/page/2/#findComment-576361 Share on other sites More sharing options...
Recommended Posts
Archived
This topic is now archived and is closed to further replies.