views:

240

answers:

2

So I am trying to store the symmetric key using DPAPI. All is well and great, but what to do with the entropy? This answered question here really doesn't provide enough insight. It seems like a slippery slope - I could use the machine store to store the entropy but then what prevents someone from getting at that as well? Note: I am storing the current key using the User Scope.

So my question is - what is the best way to store the entropy using DPAPI?

+1  A: 

Anything you store locally can be compromised. But there are steps you can take to make it more difficult. There is a document on Handling Passwords that you may consider looking over. You consider your Entropy Key a password specific to your application.

I am going to refer to your Entropy as your Key, since it is functionally an additional key.

What you don't want to do is store your key locally in an unencrypted format. Instead you want to either encrypt your key, or derive it from another, in-obvious source. Of course if your encrypt the key, then you need to store the key used to encrypt it - but often times this single layer of indirection is enough to discourage most challengers.

That would be the advantage of deriving your key. You could derive it as a hash of some other piece of constant data (needs to be something that doesn't change with revisions of your application). One trick when deriving a hash though is to combine the hash with some other constant value (like a GUID or large random number) so that someone else cannot just combine a known hash algorithm and get your key. This is a much better alternative to creating your own hash algorithm (which you should never do, unless you have a PHD in Mathematics).

At some point your are going to need some sort of key hard coded in your application. This key is either combined with some other data in a hash to create your Entropy Key, or used to decrypt the entropy key. You actually can have the key change with a new revision of your application, as long as you keep the old key for decrypting the existing key. Then you can re-encrypt it with the new key or method.

If you want the best security then you can store the Entropy key off the computer. This would require an internet connection and an SSL certificate, but then they key is never persisted anywhere locally to be discovered. To do this you can setup a more robust challenge response system so the request authentication is different each time, and the key is delivered over SSL encryption so it cannot be intercepted. Once the key is used, then it is discarded. Of course this kind of defeats the purpose of many scenarios where you are using DPAPI for local secure storage.

Whatever you do, keep in mind it will be compromised - that always happens when someone has full access to the local machine and the data stored on it. The solution to that is to keep releasing updates that change the method enough that the old crack no longer works. This will make distribution of a crack less valuable as it will be difficult to find one for the right version.

Jim McKeeth
+1  A: 

First, let me address the original post question. It boils down to the fact that the entropy must be stored under the authority of the user and/or the authority of the application if it is going to be used for persisted storage. I suppose you could use a key stored with the application to encrypt the information in the persisted store but again a malicious application would be able to access this encryption key. So, I do not feel there is a means to protect against the scenario you mention in comments. However, given what you have said is the intended use of the entropy, I do not feel it helps in solving your problem.

It sounds as if the actual problem is establishing a secure channel of communication between your client application and the server. In your design, you are exchanging keys that will be used to encrypt communication. I think that trying to use custom code to solve this issue will lead to additional security vulnerabilities.

Given all of that, I would suggest creating a WCF (Windows Communication Foundation) service that is used to retrieve sensitive information. It could obviously be used to retrieve all information, but the least amount of change would be to confine the service to sensitive information.

With WCF, you can configure both the client and the server to use a secure channel. WCF has plenty of options for establishing a secure channel of communication to the server.

<wsHttpBinding>
    <binding>
        <security mode="Transport">
            <transport clientCredentialType="Windows" />
        </security>
    </binding>
</wsHttpBinding>

Once you have a secure channel, many of the other problems are simpler such as access to the CC data. If that data is sent down a secure channel, it becomes an issue of authorization instead of channel security.

See How to: Create a Secure Session for more.

Thomas