Ubercart and credit card asymmetric encryption

Posts: 40
Joined: 09/12/2007
Getting busy with the Ubercode.

We have an Ubercart site that will be manually processing credit cards. There is a concern that if the server was compromised, a smart hacker could decrypt the credit card information. I don't see a way around this if the encryption key is the same as the decryption key. The only way to prevent this that I can see is to use an asymmetric encryption scheme (The key to encrypt is different than the key to decrypt). So, say using RSA encryption, the private key to decrypt can be kept on the clients home computer and never put on the server.

I have made a simple desktop application that generates RSA keys when it is first run. The public key info (1024 bit) can then be copied and pasted into a php encryption function. Then I believe all that is necessary to integrate into the cart is to call this encryption function just before Ubercart stores the credit card in the database:

$cc = encrypt($cc);

Then when the client wants to process an order they copy the encrypted cc info into the desktop app, where the private key is available, and it is decrypted. This seems to me perfectly secure as the decryption private key is never available on the server.

I have completed and tested the desktop app (to generate the keys and do the decrypting), and the php function to encrypt. I believe all that is left to integrate into ubercart is to add a line as mentioned above to encrypt the cc just before it is stored in the db (and change the column type in the table that stores the cc). Does anybody see these changes as potentially breaking anything in the cart? Are there any security considerations or anything else I may have overlooked?

Posts: 701
Joined: 11/05/2007
Bug FinderFAQ ModeratorGetting busy with the Ubercode.

I agree. This is a discussion I've been meaning to start. But too many things to do, too little time Smiling

While the current encryption scheme in Ubercart is better than storing the card numbers in plaintext, the fact that it also stores the key (used to both encrypt and decrypt these number) on the web server means only that there is one more step needed to steal your card numbers - it doesn't add any real protection. If your web server can be compromised to gain access to your DB, it's likely that the key can be obtained at the same time. Regardless of the strength of the encryption method, the credit card data is only as safe as the key (not very!). IMNSHO, no one should be storing these numbers in their DB. But if they insist, the current method of protecting the numbers is not adequate.

(and, BTW, after reviewing the encryption scheme used by Ubercart, I have to say it's really quite weak. As in, I'm no expert but I could crack your key before I had my morning coffee while I'm waiting for my toast to pop. Details here http://www.ubercart.org/comment/14122/Re-CC-encryption-Bazaar-needs-test...)

An asymmetric (public-key) encryption goes a long way towards addressing these issues: The fact that the private (decryption) key would not be stored on the web server means that if your web host or DB were compromised, the encrypted numbers would still be useless.

Moreover, RSA/PGP/etc. are really incomparably stronger than the current scheme, and with a reasonable length key they can't be broken. (RSA can be broken with sufficient time and computing power, but by choosing the key length appropriately it can be made as secure as desired. PGP, on the other hand, has not been shown vulnerable to an attack of this nature - it really is pretty good Smiling )

Storing the private key locally also makes it a little harder to use - all that cut-and-paste - and you still have to worry about compromising the private key, but at least all the eggs aren't in the same basket. Perhaps a little JavaScript can be inserted to run on the client side which prompts the user for the private key then automatically decrypts any displayed card numbers on the page. That would address ease of use without sending the key across the wire.

Possible drawbacks to using these encryption methods are the availability of open source (GPL) implementations in PHP. I haven't looked into this, but it occurs to me that Drupal requires a number of external services to be available, and these don't have to be PHP, just callable from PHP. A DB server, for example... I would think that a GPL encryption library, even if it's not PHP, doesn't contradict the spirit of Drupal.

I look forward to trying out your contribution. May I suggest that you code it not as described in your post above, but as a drop-in replacement for the class uc_encryption_class found in uc_store.module. That way your code can be used with minimal disruption to core. (It would be interesting if core could accommodate different encryption methods through the use of a hook...)

--

<tr>.