Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

I have a multi-tenant, SaaS application that integrates with an online payment processor. I facilitate processing transactions on behalf of my tenants by storing their secret API keys in my database, and then using those keys to make calls to the payment processor. Each tenant can have one or several user accounts; in order to keep the secret keys secret, each user account has a public/private key pair. The public key is stored unencrypted with the user account, and the private key is stored using AES with a key derived from the user's password. The secret API key is stored with each account, after being encrypted with the user's public key. With this system, if an administrator for the tenant needs to update the secret API key this can easily be done because the new API key can be encrypted and stored with each of that tenant's user's public keys.

This works well for payments that are run by a user who is logged into the system, because the API key can be decrypted on login and used to process payments. The problem is that I would like to provide an end user payment page that my tenants can direct their customers to in order to make payments. The problem is that the API key will not be available to those users, so I won't have a way to run the payments.

Any good suggestions on how to work this out? The best solution I've come up with so far (suggested, in fact, by my non-programmer wife) is to generate a random, "one-time" key and use this to encrypt the API key with AES, then embed that key in the link to the payment page but not store the link (or the key) in the database. When the end user accessed the link the API key could be decrypted and used for that payment, and then that encrypted copy could be deleted from the database. The encrypted copy would also be deleted if the invoice expired, or if the balance was paid through a different method, in order to minimize the possible exposure of having the API key in the database with the decryption keys floating around the internet.

Flaws in this scenario? Other solutions?

Replies are listed 'Best First'.
Re: Securing an API secret key
by Anonymous Monk on Aug 29, 2012 at 06:39 UTC

    Flaws in this scenario? Other solutions?

    Don't "invent" solutions, ask your credit card processor what to do, get it in writing

      Just to back up what Anonymous Monk said I will quote Professor Dan Boneh "Be careful when using crypto: A tremendous tool, but if incorrectly implemented products will work, but may be easily attacked. Make sure to have others review your designs and code. Don’t invent your own ciphers or modes." You are inventing your own mode here I think.

Re: Securing an API secret key
by locked_user sundialsvc4 (Abbot) on Aug 29, 2012 at 14:36 UTC

    I agree with the foregoing.   You must use a technique that is approved by your payment processor.   In fact, PayPal has a product-offering specifically designed to handle this scenario of “third-party payment.”

    In fact, your entire complex existing scheme might be replaceable by switching to PayPal as your payment processor.   You literally wash your hands by offloading the responsibility, securely, to them.