2

I'm thinking about the safest possible way to store secure data (eg. Credit Card numbers) with a requirement of sending them in clear text to third party API (so hashing doesn't come into play).

I've came to solution that seems to be more secure than typical 'store them encrypted and decrypt when you have to use them using the same key'.

The idea is to encrypt it and store on the application server directly after acquiring it from user with a public key.

The private key wouldn't be stored on the application server at all. Instead the application server would send the message to 3rd party API using the encrypted values.

The second part of the solution would be an HTTP Proxy on a separate server that would route the messages to the third party API and decrypt the encrypted values. The private key would be stored only on the proxy and wouldn't be stored on disk (only in RAM - each restart would require inputting the private key).

It seems, that using proxy as a black box that wouldn't need to change despite application development would help in securing it better than the application server (to which more people have to have access). Also, because of the requirement of not storing the private key on disk, it wouldn't be such a problem to enter the key after each restart of the proxy server since it wouldn't have to be restarted as frequently as an application server machine.

Any thoughts on advantages and disadvantages of such a solution? Are there any applications that could help me achieve it (proxy with ability to use custom transformation code, method of securely storing values in RAM)?

Scott Pack
  • 15,167
  • 5
  • 61
  • 91
deadbeef
  • 131
  • 2

2 Answers2

1

Quoting the Karate Kid, "Remember, the best block is not be there". (Thanks to Bill Cheswick for this quote.) In other words, the safest way to store a credit card securely is... (wait for it...) don't store it at all. Use a third-party credit card processor which stores the credit card numbers for you, so you don't have to. They may give you a handle you can use instead.

Alternatively, you can build your own service. Build a simple proxy that stores the credit card number securely, in its own database, encrypted, using an encryption key that is not known to the rest of your code. The proxy can provide an API. When a user registers their account, you send their credit card number to the proxy for storage. When a user makes a payment, you send a message to the proxy: 'charge $27 to user xyz's credit card', and the proxy is responsible for retrieving the credit card number and initiating the transaction with your credit card processor. Harden the service you use to store credit card numbers, and consider initiating some rate-limiting or auditing procedures. This way, if the rest of your code is compromised, at least the attackers cannot steal all of your users' credit card numbers.

See also How can I create a service that automatically logs onto a third-party service without storing credentials in plain text? [which asks about storing a password securely, but you can apply the same techniques to storing a credit card number], Storing Credit Card Numbers, and Storing credit cards for automatic payments?.

D.W.
  • 98,420
  • 30
  • 267
  • 572
  • Agree with the Karate Kid's master, unfortunately that's not an option. As to the second part - isn't my solution better since the secure part (proxy) is much simpler that the service you are proposing? The simpler it is, the easier it will be to secure it and there won't be need to update it as frequently as the security API you're proposing (since it's more complicated and depends on a communications scheme with 3rd party). – deadbeef Jun 06 '12 at 17:24
  • @deadbeef, if I understand your proxy proposal, I think your proxy proposal is pretty close to what I was proposing. Either would work; they seem pretty similar in security properties to me, though maybe you can see some implications that I've missed. I think you'd be fine to go with whichever one appeals to you more. – D.W. Jun 06 '12 at 17:56
0

A better approach could be usage of a HSM device for encryption of user credit card data into a separate database. Many HSM provide you with data base column level encryption feature where in the development of secure modules will ease to very high level. You will not need to have asymmetric keys, instead the HSM can generate symmetric keys for each user and those keys will be safeguarded by the HSM's security world. On top of it, to have high level security you can secure the enciphered data using challenge phrase which is created by the end user (the card holder). The SSL tunneling can be done through the HSM directly for validation of the challenge. In this way the infrastructure will not know the challenge and user card details as well.

Mohit Sethi
  • 692
  • 4
  • 7