views:

113

answers:

2

So I would like to modify a PHP / MySQL application in order to store credit card but not cvv and bank account info securely. PCI DSS require 1024 RSA/DSA. A small number of users will be given private key in order to decrypt the batch file of account info for submission to payment processors monthly. I'm unclear if it is possible to have a system that would allow the users who have signed in with normal 8 digit passwords to modify their own account info securely. It seems that this is not possible, and the encryption should be one-way (ie each user -> admins; never allowing user to decrypt their own info again), with account info never exposed back to users even over SSL connections. Or is there a proper and easy way to do this that I'm unaware of that is PCI DSS compliant?

+2  A: 

PCI DSS does not require 1024 bit RSA to encrypt. Older versions of the specification mentioned AES and 3DES by name, but I believe newer versions just specify strong encryption. Most people are using AES 256.

Encrypting data at-rest with an asymmetric algorithm doesn't really work. Symmetric algorithms work best. This allows the application to access the card data when it needs to. This doesn't mean you have to show the data to the user ever again, it just means the data is there when you need to get to it. If you're storing credit card authorization information, you'll usually need the card number for settlement. (It really depends on the features your processor has. Some of the small-business level processors store the card for you, but this is infeasible for large scale processors like Paymentech and FDMS.)

The problem is that you will have to rotate your encryption keys periodically. This is usually what screws everyone up. If you roll your own encryption, you need to make sure that you can specify n number of keys that are accessible for as long as there is data encrypted with those keys. At any point in time, only one of those keys should be used for encryption. Unless you have a deep understanding of crypto and key management in terms of PCI, you might want to go with a commercial offering. Yes, these are expensive, but you have to determine the best course with a build or buy decision making process.

Ingrian (now SafeNet) has a decent offering for a network HSM. It will manage the keys for you and do the cryptographic operations. It may also be possible to use their DB level encryption integration so that you don't have to change your application at all. (Though DB level encryption is dubiously secure in my opinion.)

This is a very deep subject; I've done a lot with PCI and suggest you hire someone to guide you through doing it properly. You'll spend a lot of money on false starts and redoing work, so get an auditor involved early to at least asses what you need and tell you how to implement the security properly.

Nathan
From the PCI DSS Glossary:Strong Cryptography: ... Effective size of the key should meet the minimum key size of comparable strengths recommendations.... that meet the following minimum comparable key bit security: * 80 bits for secret key based systems (for example TDES) * 1024 bits modulus for public key algorithms based on the factorization (for example, RSA) * 1024 bits for the discrete logarithm (for example, Diffie-Hellman) with a minimum 160 bits size of a large subgroup (for example, DSA) * 160 bits for elliptic curve cryptography (for example, ECDSA)
JM
Can you clarify why an asymmetrical key doesn't really work for data storage? The advantage I see is that I can require the authorized users to store the private key somewhere other than the server, then provide it over https when they want to export the batch file for submission to the payment processor. The key would be used in memory, and not need to be on the server file system. While I didn't recall anything about storing private keys being a problem, I just thought it was a weakness to be avoided. (If necessary one could set up Apache so the private key doesn't get logged.)
JM
Yes, I noticed the key rotation issue but you're making the importance clearer. So they should be some quarterly job that is run to read the values with the old (private) key and write them in the DB with a new (public) key.
JM
For rotation - might look at RSA RKM and see if you can find info on their method. It is automated based on a policy, and the keys are stored centrally, cached locally, and a client library does the cryptography locally. It is expensive, but it gives you a fairly high performance crypto + key management solution. I believe another company named Protegrity also has a similar solution, but implemented slightly differently. The key management area is what will give you the most headaches if it is done incorrectly.
Nathan
Asymmetric algorithms (aka public key algorithms) need both keys to encrypt and decrypt. Users are notoriously bad at keeping important information from being lost, so you may end up with some of them losing access to their data unless you are storing the private key. If you are storing both public and private key, you are essentially using them as a symmetric key (aka secret key based system). Asymmetric crypto is slower than symmetric crypto. It really depends on what you're doing. If you're just storing their data, then maybe asymmetric will work because it matches the problem domain.
Nathan
+1  A: 

You may have an easier time if you differentiate between data storage, access, and transmission.

Storage requires strong reversible encryption; the data is not useful unless you can retrieve it.

Access requires a user or process to authenticate itself before it is permitted to decrypt the data. Here's an example of a mechanism that would accomplish this:

  1. Store the data with a secret key that is never directly exposed to any user. Of course, you'll need to store that key somewhere, and you must be able to retrieve it.
  2. When each user chooses a password, use the password to encrypt a personal copy of the private key for that user. (Note: even though you're encrypting each copy of the key, security issues may arise from maintaining multiple copies of the same information.)
  3. Do not store the user's password. Instead, hash it according to standard best practices (with salt, etc.) and store the hash.
  4. When a user provides a password to log in, hash it and compare to your stored value. If they match, use the (plainitext) password to decrypt the key, which is then used to decrypt the actual data.

Transmit the data through a secure connection, such as SSL. It's reasonable (perhaps required) to allow users to access (and modify) their own data, as long as you continue to follow best practices.


Comments:

  • An 8-digit password implies a key space of 108 ~ 227 = 27 bits, which by today's standards is fairly terrible. If you can't encourage longer (or alphanumeric) passwords, you may want to consider additional layers.

  • One advantage to the multiple-layer strategy (user provides a password that is used to encrypt the "actual" key) is that you can change the encryption key transparently to the user, thereby satisfying any key-rotation requirements..

  • The standard admonition whenever you're designing a security solution is to remember that DIY security, even when following standards, is risky at best. You're almost always better off using an off-the-shelf package by a reputable vendor, or at least having a trained, certified security professional audit both your strategy and your implementation.

Good luck!

Adam Liss
My concern is that since 8 alphanumeric character passwords are so terrible, that allowing them to be used to retrieve one user's account info is a security hole. However, it is only one account. And as the system does password hashing properly brute force would be needed to crack each user account to get bank info - perhaps that's good enough.I like how 2 and 4 together work together to allow users to modify their own info. But I'm unclear how to produce the monthly batch file for submission. Agreed re: issues of role your own.
JM