CC Encryption is definitely an issue that needs to be addressed. While Lyle is technically right that any two-way encryption scheme can be decrypted if someone has the resources, it is HIGHLY unlikely if the encryption is done correctly.
Lyle is also correct that the best policy is not to store the CC numbers at all, but that is not always an option. For systems that require recurring billing, keeping the CCs in integral. So a solution needs to be found. Additionally, Ubercart (currently) stores the CC in the database between transaction stages. So if someone abandons their cart (even if they have the option checked to not store CC numbers after the transaction), the CC remains in the DB. That CC should be encrypted, even if it is only temp storage, because you never know when a user will abandon the cart, or close the browser for another reason, and if the CC will be in the DB it will be stuck and potentially exposed.
Even if MD5 were a two-way encryption methodology, it is not strong enough for CC numbers. Too may Rainbow table projects exist for it. Something stronger is needed.
Mcrypt is likely the best solution. It is relatively easy to implement and it seems solid.
Using MCypyt with AES/Rijndael (128, 192, or 256) should be MORE THAN adequate protection for storing CC numbers in an Ubercart DB table. By using MCrypt with AES/Rijndael on a credit card number with a Random Salt concantenated and then a site salt and an administratively set cipher key, those numbers would be encrypted and obfuscated beyond reasonable means for decryption.
So what I am envisioning is a DB entry into cc_num(blob) built like this
$random_salt = md5(uniqid(rand(), true));
$text = $site_salt . $cc_num . $random_salt;
$crypttext = mcrypt_encrypt(MCRYPT_RIJNDAEL_256, $key, $text, MCRYPT_MODE_ECB, $iv);
Compnents of $text:
1. $site_salt - Would be a salt that the administrator would create and store in an offline file (perhaps settings.php)
2. $cc_num is the plain test CC number
3. $random_salt is a random unique id generated on the fly for each user and stored in the DB, perhaps in a salt table that is related either to the user table, where each user would have their own salt, or to the uc_payment_credit table where each CC payment would have its own salt.
This way the "bad guys" would need more than just access to the uc_payment_credit table to be able to do anything with the encrypted credit card numbers. They could begin trying to brute force attack those numbers, but in 100+ years, when they finally succeeded, would anyone care?
To crack the encryption, they would need access to the database, AND the key stored in the protected system file (Which should be possibly be excluded from off-site backups).
The random_salt is merely there to protect against brute force attacks against the credit card table. If the entire db is compromised, the random salt only helps with obfuscation.
Now, I am not an absolute expert on this stuff. I am also not a PHP developer or Drupal Develper by training, however I am working on it. I am a ColdFusion developer and I have been researching CC and Password encryption for some projects. I am a Drupal user and I am currently setting up an Ubercart site for a friend, and when I saw that cc_num was being stored in plain text, I had to say something. If there are glaring errors in my logic, I would like to have them pointed out to me.
AES/Rijndael 192 and 256 encryption are an acceptable standard for US Government Secret and Top-Secret classified information protection link, so they are probably good enough for an online store.



Joined: 10/11/2007