10

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?

22
  • It would be helpful if you described your application in more detail. What kind of application is this: Windows service, interactive app (Windows Forms/WPF), etc? Also, how do you store and retrieve the symmetric key? I mean, if you use DPAPI with user store and store the key yourself, then only you (or someone who can log on with your credentials) can retrieve the value, in which case, I'm not sure which threat you are trying to mitigate by protecting the secondary entropy (you should worry about protecting your credentials). Commented Apr 9, 2010 at 23:43
  • When you protect it with LocalUser, any application running under the local user can access the key store. It is a windows forms application. As opposed to LocalMachine which any application running on the machine can access the store to get the key which is akin to basically having no encryption at all Commented Apr 11, 2010 at 2:18
  • Your statement is not 100% accurate. Only apps running under the SAME user account with loaded profile (it can be domain user, not necessarily local user) have access to the SAME key store. So if user X launches your Win Form and it encrypts a secret with user X's DPAPI key, only apps launched by the same user X will be able to decrypt it. Essentially, this secret is protected by user X's credentials, so as long as user X doesn't share password, I can't think of a threat you're mitigating. Could you describe a use case (scenario) you're trying to avoid? Commented Apr 11, 2010 at 5:18
  • Yes, user X runs app X (which is benign) and also runs apps Y (which is malicious) under user X. Apps Y now can access key store created by app X under user X because it is running under user X and entropy if it is stored in there also. Apparently there are malicious programs that will scan for key stores and attempt to gain access to them. Commented Apr 11, 2010 at 20:16
  • I see. Last (hopefully) question: what's the purpose of your symmetric key? Is this a user-specific key (that the app uses locally), or a key shared between multiple users (e.g. used in some remote method calls)? What kind of data is being encrypted with this key? Commented Apr 12, 2010 at 4:35

2 Answers 2

9

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.

Sign up to request clarification or add additional context in comments.

2 Comments

The optional entropy should ideally be an additional password the user uses to launch the application. Then the data cannot be decrypted even if the Windows credentials were compromised and even a Domain Admin cannot decrypt the data. The regular DPAPI master keys can be accessed by a Domain Admin.
Just as a note, a mitm attack could still easily intercept your remotely stored key (even if its SSL accessed). I think the point here is, there's not anything you can really do to make your solution bulletproof.
0

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.

8 Comments

This doesn't solve the problem, it just places the burden on the WCF server instead of the client machine.
@Jake - While the original question was related to storing the entropy value, if you read the comments you find that there is much more to the problem that the poster is trying to solve that just where to store the entropy (which I did address by saying that it must be somewhere under the control of the application). The poster was also trying to solve how to secure communication between the client and server. Btw, "putting the burden on the WCF server" is the whole point. I.e., it is outside the access and influence of the client where it has a higher chance of being compromised.
So how do you keep an impostor from creating a secure channel with the WCF server?
In reading through the comments, the poster was trying to devise a means to develop a secure channel of communication to the WCF service without using TLS. There is a lot that goes into TLS to make it secure and even then it is problematic. TLS involves both asymmetric and symmetric key exchange, an exchange of protocols, cipher methods and a host of other secure features, but the right approach is to force TLS.If the clients cannot communicate through TLS, then it is no different than rolling your own and forcing the clients to adhere to your custom solution.
I am aware of all of this, but it doesn't really answer my question. I understand the difficulty in finding a good solution to OP's problem; I came to this thread in the first place specifically for this reason. I was hoping to find an answer that would require the attacker to spend enough time on the hack to get discouraged, but it seems to me that your solution doesn't offer that.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.