.Net Design pattern for storing and retrieving sen

2019-03-31 05:57发布

问题:

Are there any reference patterns for .Net server applications relating to storing and retrieving sensitive per user information such as 3rd party credentials?

My preliminary design thoughts are along the lines of:

  1. Generate a self signed X509 certificate with appropriately strong private key,
  2. Export the certificate and key and store them on a USB key which will be locked in a treasure chest and guarded by dragons,
  3. Design my server applications to request the private key on demand from the windows current user certificate store,
  4. When installing the server application on a new server retrieve the USB key and import the certificate and and mark the private key as non-exportable.

My requirements are:

  1. Reduce the risk as much as possible of user's sensitive information getting compromised if the storage medium is compromised. In my case the storage medium could be a relational database or Amazon's SimpleDB,
  2. Reduce the risk of user's sensitive information getting compromised if the .Net server's host operating system, in this case Window's Data Center Edition, is compromised.

Update 3. Forgot to mention being able to rekey on a periodic basis is a requirement so that the same prviate encryption key isn't used for 10 years.

Problems:

  1. If the host operating system is compromised an attacker could install a malicious application to perform the same decryption operations as my .Net server.

Update Thinking about an OS compromise some more I realise there's nothing that can be done if a skilled attacker gains access but the keys should be protected from a malcontent administrator, i.e. it's more than a matter of opening a file or registry key to extract the private key.

I'm sure this problem has been solved a thousand times already, more than happy for a link answer, but searching on "security encryption" type topics is low signal high noise.

回答1:

I'm not aware of any specific design patterns regarding security of information on your .NET server application, however, ultimately, you can only do so much to secure any information that you request from the user, and specifically, store.

If you are storing any user passwords that will be used for authentication that your own application will perform, the best way of storing this is with a salted one-way hash function. This way, the user is going to provide the password, manually, in plain text every time they authenticate with your application, and you will immediately hash that plain text password and compare that with the hashed password that you have stored. Any attacker, even one with access to the raw database, would have to brute-force reverse engineer all of your salted hashes. Not impossible (given enough computing power), but certainly improbable in all reality.

If you're storing usernames/passwords that the user is providing to you, such that your application can then use these credentials to automatically "log into"/"authenticate with" another application or service on the user's behalf, well, I would suggest that you don't do this if security of that data is paramount.

Put simply, even if you encrypt these credentials (whether that be symmetric or asymmetric encryption) ultimately, that data has to be used somewhere and for that to happen, it needs to be decrypted. This is the "weak link" in the security chain so to speak.

Reduce the risk of user's sensitive information getting compromised if the .Net server's host operating system, in this case Window's Data Center Edition, is compromised.

If this were to happen, all bets are off. Having the data stored in an encrypted form no longer means anything, as if Windows can decrypt that data, so can an attacker once he has access to the machine/OS. He wouldn't even need to attempt to "export" the private key from the Windows certificate store, as he could inject his malicious code further down the decryption chain and simply intercept the decrypted data as it comes out of the decryption process.

Of course, the finest way of protecting your user's sensitive data is to never store it at all. Request it from the user each and every time, use it for whatever purpose you need it for, then dispose of it immediately. In the UK, the PCI (Payment Card Industry) Data Standards adopt this policy with regard to the CVV codes on credit cards. Merchants can store the credit card numbers, but never the CVV codes in their databases.

If you must store the data, then by all means encrypt it, but be aware that encrypting it doesn't necessarily "secure" the data, it just adds another layer of what is effectively obfuscation for an attacker who can potentially compromise your physical machine or Operating System.

If you are storing the data, you'll have to have as strong perimeter security (ie. Network security) as you can possibly get, precisely to prevent the potential for an attacker to gain access to the server's OS.

Export the certificate and key and store them on a USB key which will be locked in a treasure chest and guarded by dragons,

As well as a solid firewall and perhaps IDS system, you might want to get one of those dragons to guard your server, too! :)



回答2:

I don't know what the best solution will be , but this is what i have seen with some video game's especially games on steam. The game will first authenticate using the usual private key technique. Then, the game will download a script which is run locally. The script will then somehow , check the executable which is hosting it. The script can check if the executable is the same game or is modified. The script will call home before the game starts. If the script doesn't call home, the game server kicks the game out.

A malware writer has to somehow fool the script into thinking its the game. Whenever a malware is found to do that, the script is changed by the developer. This ensures that the game company has the ability to deactivate malwares in the wild.

You could adapt the similar technique to your application.



回答3:

In addition to the suggestion you yourself make and some of the other posters, you might consider segregating the security for database retrieval and modifications. If one account becomes compromised, the other is safe.