Re: [PHP] Help! Made a boo-boo encrypting credit cards
My merchant provider levies monthly fines based on how many of their security restrictions you fail to follow. I follow as many as are reasonably practical, but I think it's virtually impossible to follow them all, such as absurdly expensive (and probably unnecessary) hardware. IMHO, some of the restrictions are based less on reality and more on their security consulting firm's ability to frighten them. Their consulting firm's disclosed commissions on the fines creates an inherent conflict of interest. Goofily, my provider's fine structure does not differentiate between transactions that are merely processed on my server with no storage, and transactions originating from a card number stored on my server. So I have to constantly weigh the monthly fines vs. the cost of the upgrades vs. the amount of money that my various services bring in. There is no perfect solution. Nevertheless, I'm very open to any suggestions people have for transactions requiring that I keep the card number (in this case, recurring monthly charges where the customers choose not to use PayPal etc. and where too many customers would flake or get frustrated if forced to re-enter their card info every month for an annoyingly small transaction). Sorry this is getting a little off-topic for PHP. -- PHP General Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP] Help! Made a boo-boo encrypting credit cards
That's a great suggestion. I will try this and report back. It's also been suggested to me that I should have base64_encoded the encryptions before storing them in MySQL, so I'll try this option at the same time. On Mar 1, 2011, at 2:04 PM, Ashley Sheridan wrote: Onto the problem of the data you already have. Do you have a test-case that causes the problem? Try running a bunch of fictitious numbers against your code and store the results in your DB. For a decent test, you'll want to test it against a lot of numbers, store each one in plain format in the DB (use the same character encoding as you already have to see if that's part of the issue) alongside the encrypted version, then retrieve the encrypted value and test it against the original. It may take only a few dozen numbers to show the problem, it may take a thousand, but just let it run until it finds a problem. -- PHP General Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php
RE: [PHP] Help! Made a boo-boo encrypting credit cards
From: Brian Dunning My merchant provider levies monthly fines based on how many of their security restrictions you fail to follow. I follow as many as are reasonably practical, but I think it's virtually impossible to follow them all, such as absurdly expensive (and probably unnecessary) hardware. IMHO, some of the restrictions are based less on reality and more on their security consulting firm's ability to frighten them. Their consulting firm's disclosed commissions on the fines creates an inherent conflict of interest. Goofily, my provider's fine structure does not differentiate between transactions that are merely processed on my server with no storage, and transactions originating from a card number stored on my server. So I have to constantly weigh the monthly fines vs. the cost of the upgrades vs. the amount of money that my various services bring in. There is no perfect solution. Nevertheless, I'm very open to any suggestions people have for transactions requiring that I keep the card number (in this case, recurring monthly charges where the customers choose not to use PayPal etc. and where too many customers would flake or get frustrated if forced to re-enter their card info every month for an annoyingly small transaction). Sorry this is getting a little off-topic for PHP. Seems to me we have had similar discussions in the past, and not necessarily on Friday. First of all, you probably want to talk to your lawyer about the potential conflict of interest. That may need to be forwarded to a regulatory office or Attorney General for investigation. Second, do their rules conform to the OWASP recommendations and standard PCI guidelines? If they are deviating from those, or adding ridiculous requirements simply to squeeze a few extra pesos out of you, you might also want to ask your lawyer about them. Next, do they have a storage vault for credit card numbers that you can access. There shouldn't be any need for you to store them. We put numbers in our processor's vault and they give us a hash index to access them in the future. We use that for recurring charges and as a convenience so customers don't have to enter them every time they make a payment. And finally, even if they do follow the PCI regulations, you have to remember that the primary purpose of those regulations is to deflect liability from them to you when there is a problem. All they need to do is document one instance where you don't follow the rules and they are off the hook for damages. Guess where that puts you. Bob McConnell -- PHP General Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP] Help! Made a boo-boo encrypting credit cards
I just wanted to ping this, as it's becoming a serious problem. I hope someone can help. On Feb 11, 2011, at 2:42 PM, Brian Dunning wrote: Hey all - I'm using mcrypt to store credit cards into MySQL. About 90% of them decrypt fine, but about 10% decrypt as nonsense (b1�\�JEÚU�A��� is a good example). Maybe there is a character that appears in about 10% of my encryptions that's not being encoded properly??? // Encryption is set up at the top of the script: $crypto = mcrypt_module_open('rijndael-256', '', 'ofb', ''); $iv = mcrypt_create_iv(mcrypt_enc_get_iv_size($crypto), MCRYPT_DEV_RANDOM); $ks = mcrypt_enc_get_key_size($crypto); $key = substr(md5('my_funky_term'), 0, $ks); // When the card number is collected by the form, it's encrypted: $cc_number = addslashes($_POST['cc_number']); mcrypt_generic_init($crypto, $key, $iv); $cc_encrypt = mcrypt_generic($crypto, $cc_number); mcrypt_generic_deinit($crypto); // This is written to the database: $query = update accounts set cc_encrypt='$cc_encrypt', encrypt_iv='$iv', other_fields='$other_stuff' where id='$account_id' limit 1; $result = mysql_query($query) or die(mysql_error()); Both the cc_encrypt and encrypt_iv fields are tinytext, latin1_swedish_ci, MyISAM, MySQL 5.0.91 In another script, when I retrieve, I first set it up at the top of the script exactly like step #1 above, then retrieve it like this: mcrypt_generic_init($crypto, $key, $row['encrypt_iv']); $cc_number = trim(mdecrypt_generic($crypto, $row['cc_encrypt'])); mcrypt_generic_deinit($crypto); Most of them are good, a few of them are bad. Can anyone see anything I'm doing wrong or a case I'm not covering? Thanks much. -- PHP General Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php -- PHP General Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP] Help! Made a boo-boo encrypting credit cards
On Tue, Mar 1, 2011 at 12:34 PM, Brian Dunning br...@briandunning.com wrote: I just wanted to ping this, as it's becoming a serious problem. I hope someone can help. On Feb 11, 2011, at 2:42 PM, Brian Dunning wrote: Hey all - I'm using mcrypt to store credit cards into MySQL. About 90% of them decrypt fine, but about 10% decrypt as nonsense (b1�\�JEÚU�A��� is a good example). Maybe there is a character that appears in about 10% of my encryptions that's not being encoded properly??? // Encryption is set up at the top of the script: $crypto = mcrypt_module_open('rijndael-256', '', 'ofb', ''); $iv = mcrypt_create_iv(mcrypt_enc_get_iv_size($crypto), MCRYPT_DEV_RANDOM); $ks = mcrypt_enc_get_key_size($crypto); $key = substr(md5('my_funky_term'), 0, $ks); // When the card number is collected by the form, it's encrypted: $cc_number = addslashes($_POST['cc_number']); mcrypt_generic_init($crypto, $key, $iv); $cc_encrypt = mcrypt_generic($crypto, $cc_number); mcrypt_generic_deinit($crypto); // This is written to the database: $query = update accounts set cc_encrypt='$cc_encrypt', encrypt_iv='$iv', other_fields='$other_stuff' where id='$account_id' limit 1; $result = mysql_query($query) or die(mysql_error()); Both the cc_encrypt and encrypt_iv fields are tinytext, latin1_swedish_ci, MyISAM, MySQL 5.0.91 In another script, when I retrieve, I first set it up at the top of the script exactly like step #1 above, then retrieve it like this: mcrypt_generic_init($crypto, $key, $row['encrypt_iv']); $cc_number = trim(mdecrypt_generic($crypto, $row['cc_encrypt'])); mcrypt_generic_deinit($crypto); Most of them are good, a few of them are bad. Can anyone see anything I'm doing wrong or a case I'm not covering? Thanks much. -- PHP General Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php -- PHP General Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php Could it be that the addslashes is creating a \0 (null) value? That might screw up the decryption routine. -- Bastien Cat, the other other white meat -- PHP General Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP] Help! Made a boo-boo encrypting credit cards
On Fri, Feb 11, 2011 at 4:42 PM, Brian Dunning br...@briandunning.com wrote: Hey all - I'm using mcrypt to store credit cards into MySQL. About 90% of them decrypt fine, but about 10% decrypt as nonsense (b1�\�JEÚU�A��� is a good example). Maybe there is a character that appears in about 10% of my encryptions that's not being encoded properly??? // Encryption is set up at the top of the script: $crypto = mcrypt_module_open('rijndael-256', '', 'ofb', ''); $iv = mcrypt_create_iv(mcrypt_enc_get_iv_size($crypto), MCRYPT_DEV_RANDOM); $ks = mcrypt_enc_get_key_size($crypto); $key = substr(md5('my_funky_term'), 0, $ks); // When the card number is collected by the form, it's encrypted: $cc_number = addslashes($_POST['cc_number']); mcrypt_generic_init($crypto, $key, $iv); $cc_encrypt = mcrypt_generic($crypto, $cc_number); mcrypt_generic_deinit($crypto); // This is written to the database: $query = update accounts set cc_encrypt='$cc_encrypt', encrypt_iv='$iv', other_fields='$other_stuff' where id='$account_id' limit 1; $result = mysql_query($query) or die(mysql_error()); Both the cc_encrypt and encrypt_iv fields are tinytext, latin1_swedish_ci, MyISAM, MySQL 5.0.91 In another script, when I retrieve, I first set it up at the top of the script exactly like step #1 above, then retrieve it like this: mcrypt_generic_init($crypto, $key, $row['encrypt_iv']); $cc_number = trim(mdecrypt_generic($crypto, $row['cc_encrypt'])); mcrypt_generic_deinit($crypto); Most of them are good, a few of them are bad. Can anyone see anything I'm doing wrong or a case I'm not covering? Thanks much. Just a WAG, but when I first was working with mcrypt, it would append spaces to the encrypted value. I would have to TRIM() everything for processing or decryption. BTW, we also elected *not* to store card numbers, only the last 4 digits. -- PHP General Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP] Help! Made a boo-boo encrypting credit cards
On Feb 13, 2011, at 12:44 AM, Richard Quadling wrote: You are using addslashes($_POST['cc_number']). Considering a credit card number is purely numeric, the addslashes would seem to be redundant as you don't need to escape numbers. I do that routinely to all input fields as one additional layer of protection against injection attacks. And you can run a Luhn10 check against the card number to make sure it is valid before storing it. I do that as well. -- PHP General Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP] Help! Made a boo-boo encrypting credit cards
On 11 February 2011 22:42, Brian Dunning br...@briandunning.com wrote: Hey all - I'm using mcrypt to store credit cards into MySQL. About 90% of them decrypt fine, but about 10% decrypt as nonsense (b1�\�JEÚU�A��� is a good example). Maybe there is a character that appears in about 10% of my encryptions that's not being encoded properly??? Unrelated to the code, but considering the frequency of credit card theft from big sites, is it really safe to store CC details, even if they are encrypted? Considering the site's code CAN decrypt it, it wouldn't be that difficult to use your code to get the card details. Sure, having the details is a benefit to the client in terms of saving them the hassle of entering the card details for each purchase/usage, but how secure is it overall? Related to the code, do you validate the card details first? You are using addslashes($_POST['cc_number']). Considering a credit card number is purely numeric, the addslashes would seem to be redundant as you don't need to escape numbers. And you can run a Luhn10 check against the card number to make sure it is valid before storing it. Richard. -- Richard Quadling Twitter : EE : Zend @RQuadling : e-e.com/M_248814.html : bit.ly/9O8vFY -- PHP General Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php
[PHP] Help! Made a boo-boo encrypting credit cards
Hey all - I'm using mcrypt to store credit cards into MySQL. About 90% of them decrypt fine, but about 10% decrypt as nonsense (b1�\�JEÚU�A��� is a good example). Maybe there is a character that appears in about 10% of my encryptions that's not being encoded properly??? // Encryption is set up at the top of the script: $crypto = mcrypt_module_open('rijndael-256', '', 'ofb', ''); $iv = mcrypt_create_iv(mcrypt_enc_get_iv_size($crypto), MCRYPT_DEV_RANDOM); $ks = mcrypt_enc_get_key_size($crypto); $key = substr(md5('my_funky_term'), 0, $ks); // When the card number is collected by the form, it's encrypted: $cc_number = addslashes($_POST['cc_number']); mcrypt_generic_init($crypto, $key, $iv); $cc_encrypt = mcrypt_generic($crypto, $cc_number); mcrypt_generic_deinit($crypto); // This is written to the database: $query = update accounts set cc_encrypt='$cc_encrypt', encrypt_iv='$iv', other_fields='$other_stuff' where id='$account_id' limit 1; $result = mysql_query($query) or die(mysql_error()); Both the cc_encrypt and encrypt_iv fields are tinytext, latin1_swedish_ci, MyISAM, MySQL 5.0.91 In another script, when I retrieve, I first set it up at the top of the script exactly like step #1 above, then retrieve it like this: mcrypt_generic_init($crypto, $key, $row['encrypt_iv']); $cc_number = trim(mdecrypt_generic($crypto, $row['cc_encrypt'])); mcrypt_generic_deinit($crypto); Most of them are good, a few of them are bad. Can anyone see anything I'm doing wrong or a case I'm not covering? Thanks much. -- PHP General Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php