Code Newbie
News     Forums     Search     Members     Sign Up    

My Code Newbie
Username

Password

Articles/Snippets
ASP Classic
ASP.NET
C
C#
C++
HTML / CSS
Java
Javascript
Linux / BSD
Perl
PHP
Python
Ruby
SQL
VB 6
VB.NET

C.N. Friends
  Planet Rome

Link to Us!
Code Newbie
  Code Newbie
    forums
Old 02-14-2005, 07:17 AM   #1 (permalink)
sde
Moderator
 
sde's Avatar
 
Join Date: May 2002
Location: us.ca
Posts: 4,490
sde is on a distinguished road
Credit Card Storage and Security:

I've been working on a billing manager for a new online business. It is a subscription service which would require monthly billing.

I've been working with PHP's mcrypt library. I could store the cc# in my web database encrypted, but then the question is where do I store the key?

There are 2 points where the encryption/decryption would happen. 1. when the customer signs up for the first time and the cc# is encrypted and put in the database. 2. when the monthly invoice is processed.

I can think of ways to accomplish this if I were willing to do things manually, but I really want to automate the process.

Nothing is un-hackable, but I can certainly try to make it more difficult. The best solution so far is to store the cc processing script on a different server with the key. This server could sit behind a firewall and just run a daily cron to process the payments. It would still have to communicate with the web database, but at least the key would be off the web server.

The problem with that is how do I encrypt the credit card initially when they sign up? Maybe that will be the only manual process. I could store half of the credit card on the web database, and have the other half emailed to me. Once I get the order, I can encrypt the card # manually and update the web database with the customer records.

Any thoughts on this?
__________________
Mike
sde is offline   Reply With Quote
Old 02-14-2005, 10:05 AM   #2 (permalink)
Belisarius
Java fanboy
 
Belisarius's Avatar
 
Join Date: Aug 2003
Posts: 1,161
Belisarius is on a distinguished road
Hmmm . . . how about encrypting it using a hash of the user's password? Then all the CC# would have different encryptions based on a crypt of the user's password. I assume you're already using MD5 or something to hash the user's password.
__________________
GitS
Belisarius is offline   Reply With Quote
Old 02-14-2005, 10:17 AM   #3 (permalink)
sde
Moderator
 
sde's Avatar
 
Join Date: May 2002
Location: us.ca
Posts: 4,490
sde is on a distinguished road
when the user changes their password, then the key will be lost. also, if a hacker was to just look at the script, they would be able to see where the key was coming from.
__________________
Mike
sde is offline   Reply With Quote
Old 02-14-2005, 11:10 AM   #4 (permalink)
Belisarius
Java fanboy
 
Belisarius's Avatar
 
Join Date: Aug 2003
Posts: 1,161
Belisarius is on a distinguished road
If the user changed their password, the CC# would need to be re-encrypted, but that can happen automatically. As for the hacker, are we talking about someone sniffing or someone who's compromised your server?
__________________
GitS
Belisarius is offline   Reply With Quote
Old 02-14-2005, 11:23 AM   #5 (permalink)
sde
Moderator
 
sde's Avatar
 
Join Date: May 2002
Location: us.ca
Posts: 4,490
sde is on a distinguished road
well the only reason to encrypt the password in the first place is in case someone compromises the server. since the credit card processing would otherwise be processed on the server through ssl to the merchant bank, i'm not too concerned about a sniffer.

so, essentially encrypting the cc# with the user's password would still be storing the key on the server.

if i have a lot of live credit cards in my database, i could definately be identified as a target to anyone or group looking for this data. if someone was skilled enough to hack into the server, then i would not doubt that it would be too difficult for them to read my credit card processing script and figure out where the key was comming from.

my potential solution is to run the processing script off-site from behind a tight firewall. the encrypted password would be requested from the off-site server, decrypted, then sending the request to the bank via ssl.

this would at least make it so the hacker could not decrypt the cc#'s with a key they found on the web server. they would have to somehow find the ip of the server that was processing the credit cards, then get in through the firewall, before they could even attempt to compromise the off-site server.

i know i'm repeating myself a bit but it helps make the situations more clear for me.
__________________
Mike
sde is offline   Reply With Quote
Old 02-14-2005, 12:03 PM   #6 (permalink)
Belisarius
Java fanboy
 
Belisarius's Avatar
 
Join Date: Aug 2003
Posts: 1,161
Belisarius is on a distinguished road
So you want a "black box" of sorts that an encrypted pass goes into and comes out unencrypted?

I'd suggest hard coding it into a compiled language then. That way someone can't simply open it up in a text editor and see the password.
__________________
GitS
Belisarius is offline   Reply With Quote
Old 02-14-2005, 12:54 PM   #7 (permalink)
technobard
Centurion Nova Prime
 
technobard's Avatar
 
Join Date: May 2002
Location: Oak Park, IL (USA)
Posts: 285
technobard is on a distinguished road
I hate to use the phrase, but for the encryption side, one idea is to use "web services", or something like it. On a server behind your firewall, pass the cc#, account#, etc. via SOAP call (or something less complicated) to a service whose only function is to encrypt the data and insert/update the record in a separate database. The key would be safely away from the webserver, cc# would be stored separately from the customer name, address, etc., and the info would still get encrypted in real time. If someone gained access to the webserver and wanted to be malicious, they could figure out what data your service needed and "update" all of your customer's cc info. You could come up with any number of safeguards to limit the damage, but I would suggest using an effective date range for your cc record. When a new update comes in, expire the old record by changing a date field, move the old record to an archive table, and insert the new record.

For monthly processing, you could either decrypt in a script as you mentioned, or setup a decryption service. This is basically Belisarius' black box idea stated a different way.

Just my two cents.
__________________
It takes 2 points to draw a straight line, but at least 3 points to draw a conclusion.
technobard is offline   Reply With Quote
Old 02-14-2005, 06:22 PM   #8 (permalink)
idx
Senior Grasshopper
 
idx's Avatar
 
Join Date: Jun 2003
Location: FL
Posts: 317
idx is on a distinguished road
Always a slippery subject.. I like the SOAP idea [minus the insanity of SOAP ] with the use of mcrypt and the like vs md5. Still need to devise a good way to safeguard the data from a compromised webserver..

-r
idx is offline   Reply With Quote
Old 02-14-2005, 10:29 PM   #9 (permalink)
teknomage1
Jack of all trades
 
teknomage1's Avatar
 
Join Date: Feb 2005
Location: Los Angeles
Posts: 598
teknomage1 is on a distinguished road
Send a message via AIM to teknomage1
Why not have a temporary key that's randomly generated either from /dev/random or the current time in microseconds, and send the temp key plus the encrypted cc# in two seperate messages to the storage server where it's decrypted then recrypted with a proper key. That way the malicious attacker would have to intercept the cc# as it was entered to actually get at the info.
teknomage1 is offline   Reply With Quote
Old 02-15-2005, 05:00 AM   #10 (permalink)
idx
Senior Grasshopper
 
idx's Avatar
 
Join Date: Jun 2003
Location: FL
Posts: 317
idx is on a distinguished road
Might also be worth looking into using gnupg for encryption before sending to the backend server.

-r
idx is offline   Reply With Quote
Old 02-24-2005, 08:46 AM   #11 (permalink)
sde
Moderator
 
sde's Avatar
 
Join Date: May 2002
Location: us.ca
Posts: 4,490
sde is on a distinguished road
http://www.phpmag.net/itr/online_art...odeid,114.html

came across this excellent article on mcrypt related to this topic.
__________________
Mike
sde is offline   Reply With Quote
Old 03-16-2005, 04:33 PM   #12 (permalink)
webcomplete.com
Registered User
 
Join Date: Mar 2005
Posts: 14
webcomplete.com is on a distinguished road
how about dont store the key anywhere and maybe create a page where you enter a key before you view reports or run transactions. after entering the key in the page, save it in your session. then anytime you view reports or run transactions, have the code read from your session to get the keys. of course if you die, no one will ever be able to run anymore transactions or view reports.... just a thought
webcomplete.com is offline   Reply With Quote
Old 03-16-2005, 04:45 PM   #13 (permalink)
sde
Moderator
 
sde's Avatar
 
Join Date: May 2002
Location: us.ca
Posts: 4,490
sde is on a distinguished road
that sounds like the most secure way, .. not storing a key anywhere, but this would require manual processing everyday which i'm not too hot on.

currently i don't store cc#'s myself, and the bank has a recurring billing manager, but it leaves much to be desired in the way of features.

after a lot of research, i do have an automated method in mind which should be as secure as i can get it without having to manually process everyday. it's just that talking about it in any detail in public will be a hole in the first line of defense
__________________
Mike
sde is offline   Reply With Quote
Old 04-04-2005, 10:32 AM   #14 (permalink)
Mazzman
Registered User
 
Join Date: Mar 2005
Posts: 7
Mazzman is on a distinguished road
Sorry of the late posting... Im a new memeber If this is still an issue for you read below. If you would like to see some source code let me know.

I have had a need to encrypt Querystrings on my websites in the past. My solution was to "borrow" the RC4 encoding and decoding algorithms and created a VB DLL, ASP function, and an Actuate Libaray tool capable of perform this task. This is the same formula that was used by PGP about 5 years ago, and my still be inuse for all I know.

Your can store the Key in your database, or a var in your code,
and then store the encrypted output in you Database, or transmit it ... or whatever...

SideNote about the RC4 Encryption formula: Someone apparenlty published this algorithm about 10 years ago on a newsgroup. I found the posting and wrote some VBScript code that does the same thing.
Mazzman is offline   Reply With Quote
Old 07-20-2005, 09:42 PM   #15 (permalink)
patrick82
Registered User
 
Join Date: Jul 2005
Posts: 1
patrick82 is on a distinguished road
Question How about doing this

How about you generate a key using code to generate a random string and use that as the key. at that instant your script emails 1 the key lets say peter@server1.com and the encrypted card# to peter@server2.com using ssl to send the emails. that way the key changes each time a card is processed. you then download your emails (with ssl) from the 2 different mail servers and put them together with decryption script run on your local machine with a copy of PHPdev or something as a aweb server on local computer. That way if a hacker did happen to hack your script they would also have to hack 2 mail servers in time before you download your emails. and if you do that regularly would be fine. I know this means manual processing the cards at the end of the day but does everyone think this is a good idea if im willing to process manually at the end of the day
patrick82 is offline   Reply With Quote
Reply

Bookmarks

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are On



All times are GMT -8. The time now is 04:29 PM.


Powered by vBulletin® Version 3.7.0
Copyright ©2000 - 2008, Jelsoft Enterprises Ltd.
Search Engine Optimization by vBSEO 3.0.0 RC8





Copyright © 2000-2008, Milano Interactive
Web Hosting provided by Portal 360 Web Hosting