5

I have a requirement to store credit card details (not storing is NOT an option).

Using mcrypt with mcrypt_dev_random to generate init_vector takes varying ages to encrypt/decrypt but seems is the most 'secure' option. mcrypt_dev_urandom MUCH quicker but not suitable for long term storage - as I have read.

Looking at GnuPG as a possible alternative and would like some opinions/heads up on these if possible.

AlienWebguy
  • 76,997
  • 17
  • 122
  • 145
Ian Wood
  • 6,515
  • 5
  • 34
  • 73
  • Securely storing credit cards is a distinctly non-trivial undertaking and if you're asking on Stack Overflow about how to go about doing it, you have virtually no hope of doing it properly or legally. – user229044 Oct 22 '12 at 14:58
  • @meagar i'm comfortable with everything but the options that introduce more work in the process traded off against speed. – Ian Wood Oct 22 '12 at 15:53
  • Wow. What product are you working on? I want to avoid it like the plague. "So long as it doesn't delay things" is the worst possible attitude you could have when dealing with storing credit card numbers. Do you understand the *massive* legal ramifications for *you personally*, not your client, if you do this wrong? Do you understand that this is not something you can stub in and flesh out the details later? You absolutely do not want to do this yourself. You *will* get it wrong and the results will be disastrous for everybody involved. – user229044 Oct 22 '12 at 16:42
  • What you need to do is give up any hope of implementing this yourself, and contact a professional [3rd party](http://en.chasepaymentech.ca/payment_gateway.html) who knows what they are doing. Even then, they will audit your system to make sure it's secure enough to interface with *their* system. This isn't a joke, this is literally as serious as security gets on the Internet. – user229044 Oct 22 '12 at 16:47
  • @meagar I am indeed aware of the ramifications and I certainly don't remember saying I WANTED to sacrifice anything for speed - the whole premise of this was to gauge solutions - and not doing this on our system is an option. further down I do mention that we would use more than one provider - hence the question - if we only ever used one provider and didn't switch then it would not be an issue. – Ian Wood Oct 22 '12 at 18:16
  • @meagar perhaps you misread my 'I'm comfortable everything but the options that introduce work' as I happy to do what ever so long as it doesn't take time - sorry did NOT mean that in the slightest. – Ian Wood Oct 22 '12 at 18:24

3 Answers3

6

If you really want to store credit card information securely, there's a standard for it: Payment Card Industry Data Security Standard. And it's a lot more involved than using one specific encryption algorithm. It requires you to store parts of the card details on two physically separate machines, among many other things. And even if you follow the PCI standard to the letter, experts argue you're still not entirely secured. Anything less than that is pretty much not worth discussing in detail, since the overall level of security is so low that it hardly makes a difference.

deceze
  • 510,633
  • 85
  • 743
  • 889
  • OK - back a step or three - would using something 'less' secure like the unblocking random number generator and one of a few algorithms based on some metric and then splitting the resulting encrypted data across physical systems be favorable... basically is there a situation where it is acceptable to use the less random method of vector creation for the sake of speed? – Ian Wood Oct 22 '12 at 15:39
  • @Ian Speed should really be the least of your concerns. It's never going to take more than a few fractions of a second, maybe *one* second, to encrypt/decrypt. The goal is to make it secure, right? Well, even if you nail the encryption process, what you need to do to make it really secure is to lock down the systems this is running on. If nobody can get into your system, even unencrypted storage is secure enough. But the weak spot is somebody gaining access to all the pieces necessary to decrypt the number; then the specific way of encrypting it hardly matters. PCI covers all this... – deceze Oct 22 '12 at 16:11
  • @deceze actually the method of generating randomness for the initialization vector can take a significant amount of time - using mcrypt_dev_random on *nix waits for entropy pool to fill - test have shown encryption taking over 200 s! – Ian Wood Oct 22 '12 at 18:10
  • final thoughts on this (hopefully)... - I've encrypted the data. stored the IV with the cipher text, sharded the base64 encoded cipher and storing over multiple physical machines; the sharding can cope with 1 node missing and still rebuild. I've requested some expert consult - when that happens who knows but hoping this is much further down the line to meeting compliance. – Ian Wood Oct 23 '12 at 15:51
  • @deceze "store parts of card details on two physically separate machines" <- are you sure about that one? I couldn't find anything such in the SAQ-D questionnaire. – eozzy Dec 10 '12 at 14:05
  • @Nimbuz I admit to not having learned about PCI in detail and was just going on fragments from things I've heard. I'll remove that part as not properly researched and validated. I'm pretty certain you need to at least keep the decryption keys on a different machine though. – deceze Dec 10 '12 at 14:30
  • @deceze yes decryption keys need to be on a separate server but it also doesn't have to be in a PCI compliant environment. – eozzy Dec 10 '12 at 15:05
4

Remember: the First Rule of Cryptography is "don't do it yourself".

MCRYPT_DEV_URANDOM is enough for robust encryption, but "managing credit card information" is a much more complicated affair than simply "encrypt 'em all and let God sort out His own".

That "not storing is NOT an option" sounds to me as if you (or better, those above you) Are Doing It Wrong. You should not be researching this, or be the one to propose a solution. Do not be the fall guy.

https://www.pcisecuritystandards.org/merchants/how_to_be_compliant.php

LSerni
  • 55,617
  • 10
  • 65
  • 107
  • thankfully I don't make the calls and as such don't take the wrap! but I do hear you. the requirement is basically due to different payment providers being used so we need to be able to switch without having the user re-enter details. I'm not saying thats a valid reason - just what has been dictated... – Ian Wood Oct 22 '12 at 15:41
  • In that case, I will partially take back the "don't do it yourself" and suggest to encrypt every user's CC data with the key of that one user (he *should* have to reenter those details if he ever resets the account password). – LSerni Oct 22 '12 at 15:50
3

For you the most important question is, what you need for PCI compliance. Don't produce some homebrew encryption. Read up on what it requires, and preferable delegate the credit card stuff to a specialized payment processor.

Using mcrypt with mcrypt_dev_random to generate init_vector takes varying ages to encrypt/decrypt but seems is the most 'secure' option. mcrypt_dev_urandom MUCH quicker but not suitable for long term storage - as I have read.

This shows some misunderstandings. For one an IV doesn't need to be secret. The quality of random numbers is less important.

But even for keys, /dev/urandom is good enough, provided it was seeded with sufficient entropy initially.

CodesInChaos
  • 106,488
  • 23
  • 218
  • 262