Securely Storing Optional Entropy While Using DPAPI
Asked Answered
R

2

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?

Rosamariarosamond answered 6/4, 2010 at 14:46 Comment(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).Aleph
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 allRosamariarosamond
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?Aleph
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.Rosamariarosamond
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?Aleph
The key is for an AES 256 encryption of credit card data between local application and credit card gateway application. It needs to be strong as possible per PA-DSS requirements. It is only used by the one app on each machine.Rosamariarosamond
So the AES key is only used locally for encrypting/decrypting the credit card number, right? I assume that the key can be different on each machine and per each user (if it's a multi-user machine). You just need the app to be able to encrypt/decrypt data locally for a particular user. Correct?Aleph
The key has to be the same on the server and client for encryption/decryption since it is symmetric. The data is encrypted, sent somewhere, and then decrypted. Server app will generate keys and client will have ability to store generated keys. The keys will be inputted manually in a key generator app.Rosamariarosamond
Then you only use the AES key for encrypting/decrypting credit card number during client/server communication? Sorry for asking so many questions, but I'm trying to figure out what would be the best recommendation for your case (since your original questions does not have a one-size-fits-all answer), and with each response, I have more questions. Like you say that server will generate symmetric keys, but then you say that keys will be manually entered, which is confusing. Also, why plural (keys vs. key)? Will there be more than one? Why not use SSL or public keys instead of AES?Aleph
The reason we can't use SSL is because some of the sockets of other clients don't support SSL (older embedded hardware). Not trying to be vague, just not provide with useless details. Basically, all clients and server would use same symmetric encr/decr key. This key needs to be secured along with the entropy. The key generator program can generate keys and securely store it in a cipher.dat file using DPAPI or allow for "custom" data entry of a key. That's where the server would generate the master key and all the clients would have the same key program and manually enter and store the key.Rosamariarosamond
Let me see if I got it. An admin enters or generates an AES key and stores it on the server (I assume it's stored protected in some way). Now this AES key (or the steps to generate it) are passed to clients. Each client (user) follows instructions to enter or generate the key and the key is stored locally on the client encrypted with DPAPI and entropy. When the user enters credit card number the client program uses the AES key to encrypt the credit card number and the encrypted value is sent over the wire to the server. The server then uses the same AES key to decrypt the value. Right?Aleph
correct. The entropy has to be secured somehow since the entropy is needed to also open the key store that is protected via DPAPI. That's the dillema.. when does the key protection stop?Rosamariarosamond
@Changeling - Is this application entirely local or does it communicate with a central database or service? It sounds like there are two different issues here.The first is the secure (read: encrypted) channel between the app and the central store and the second is the access to specific data. If the channel is secured, then it would be simpler to have the server do all the special decryption of special data based on authorization and send it down the secure channel. Is the problem in securing the chanel or the special encryption/decryption?Martie
@Changeling - Continuing, if the channel between the app and the server is secure, then is encrypting that data again necessary? If it was then the solution is asymmetrical encryption instead of symmetrical. I.e., allow the app to get the public key from the server for all to see and it uses that public key to encrypt the CC number such that the private key only exists on the server and can only be decrypted there.Martie
We discussed using OpenSSL to encrypt the channel but we found it would be easier for our customers to type in a generated or custom key and have it be stored rather than load an X.509 certificate and keep it updated.Rosamariarosamond
The application is local, but credit card processing is done at the server. It has its own databases for redundancy but also sends information to the server to be stored and aggreggated. There are multiple clients and they all do the same which the server will take their data and aggreggate. All the clients run the same, identical application.Rosamariarosamond
@Changeling - Is the database SQL Server? The reason I ask is that with SQL Server you can simply require that all communication to the database be encrypted at the protocol level.Martie
@Martie - I think the issue is client-to-server communication not server-to-database, so protocol level encryption would not help. @Changeling - From what you've described, I don't see a way to provide meaningful protection of the entropy. Any suggested approach (like deriving entropy at run time, obfuscating it, etc) just makes it slightly more non-obvious, and not sufficiently deterrent for potential hackers, and since your app deals with money, I would not bet on any such type of protection. There is simply no way to make it secure with your application architecture.Aleph
@Changeling - Cont: There may be better ways -- say, if the customer has to enter some data every time he/she uses the application, so you can derive the entropy from the user-defined value -- but without understanding the low level details of the application, it's impossible to give a good recommendation. The BKM would be: don't do what you're trying to do, and use a standard technology (SSL, PKI), but if you cannot follow the BKM, everything else will not give you a secure solution.Aleph
@Alex Davis - I'm not sure we are discussing the same thing. With SQL Server, you can mandate that all communication, including any communication from a client app to the database, be encrypted at the protocol level. It does means that literally all traffic to the database is encrypted (Management Studio, Client App, Website, sqlcmd etc.) but that would secure any channel of communication between the app and the database presuming that is the only connection.Martie
@Thomas: It's not SQL, but Paradox 5.0. Server and client use the same database format so SQL is not possible at this point.Rosamariarosamond
@Changeling - RE: database. Np. I would agree with Alek Davis in the sense that you should seek a standard technology to channel security. One possibility, would be to create a WCF service configured for secure channel communications that your app accesses to retrieve sensitive information such as the credit card number (or all data).Martie
T
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.

Traveller answered 9/4, 2010 at 22:57 Comment(2)
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.Fischer
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.Alyciaalyda
M
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.

Martie answered 15/4, 2010 at 15:51 Comment(8)
This doesn't solve the problem, it just places the burden on the WCF server instead of the client machine.Catholicon
@Catholicon - 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.Martie
So how do you keep an impostor from creating a secure channel with the WCF server?Catholicon
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.Martie
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.Catholicon
@Catholicon - Which issue are you trying to solve here? The OP outlined multiple issues in the original post and comments. If the problem is the transport protocol to the service, the answer is use TLS (which is what I stated). That completely addresses the issue of secure communication to the service. Is the issue access to the service itself? Is the issue is storage of sensitive information by the service using symmetrical encryption?Martie
I am trying to solve the primary issue indicated by OP: "What is the best way to store the entropy using DPAPI?" Your solution of "store it somewhere else and open up a secure channel" only protects against listeners. Certainly it would be much more secure to not send the data over a network at all, right? Anyone who has access to the client machine has access to all the credentials necessary for accessing the secure channel, but now you've opened up the possibility that a remote listener can figure out the entropy too.Catholicon
What is missing in your question is the intended use of the entropy. The OP was trying to use the entropy to secure the channel of communication. That approach is fundamentally flawed. Instead, use TLS to secure the communication. If you are using TLS, then you have solved Man-in-the-middle listeners. Now, in what other way is said entropy to be used? Storage? Authentication? If secure communication is the only use, then there is nothing to store if you are using TLS.Martie

© 2022 - 2024 — McMap. All rights reserved.