views:

458

answers:

1

I have a Windows service that will normally be run using the Local System Account (although in some installations it may as a specific user account).

The service is using WCF, with communication secured using X509 certificates.

My question is, where is the best place to store the certificate (and private key)?

If using a certificate store is the best approach, which one should I use to ensure that only Administrators and the service can access the private key?

Alternatively, a simple option would be to simply store both as a PFX file on disk, and use ACLs to ensure only Administrators and the service have access to it. What are the pros and cons of this approach vs using a certificate store?

EDIT To clarify, I am using C# with the .NET Framework 3.5

+2  A: 

First of all I recommend you to hold certificate in a certificate store with private key saved as non exportable. Now some arguments.

There are different ways to save on a machine a private secret or other private information. The most old way is LsaStorePrivateData and LsaRetrievePrivateData API (see http://msdn.microsoft.com/en-us/library/ms721818%28VS.85%29.aspx). It has restriction to the number of secrets, but all secrets can be divided to local, global, and machine.

Next way is using DPAPI (see http://msdn.microsoft.com/en-us/library/ms995355.aspx): CryptProtectData and CryptUnprotectData in our case.

I add references to this two ways because you want compare different possible ways to be sure that your way is the best for your task.

I think the most important question which you should ask is: which is the best way to protect my private key? I think you should choose the way, which protect your key to be copied. So I recommend you use certificate store. In a certificate store you can hold private key marked non exportable. This is the main advantage in my opinion. You can deploy the certificate with the corresponding private key with different ways. Be sure, that the private key saved on the machine are not marked as exportable.

Using of PFX file on disk gives you not this advantage. Moreover either your PFX is not encrypted or you receive a problem where you should save the password to the PFX file. So you have to use DPAPI (CryptProtectData and CryptUnprotectData) or LSA API (LsaStorePrivateData and LsaRetrievePrivateData) and the password can be exported.

Oleg
The 'non exportable' flag doesn't really add security - it is trivial to export such keys using a tool like Jailbreak (www.isecpartners.com).
Cocowalla
@Cocowalla Thanks you the interesting information! It's new for me and I will be search more information about this tool, but I don't believe that this tool can export private key from a smart card or other hardware solution. Smart card of cause is not good for a solution for the server, but other hardware based certificate store can solve the problem. Moreover Jailbreak could not more work after the next security fix for Windows. To tell the trust I don't know a solution which is better as certificate store at least from the architecture side.
Oleg
You are right that Jailbreak cannot export from smart cards. If a certificate store is the best solution, which store should I use? Local Machine store? How is this secured (that is, in terms of _who_ can access the private key)?
Cocowalla
Good question, At the beginning you can use really standard certificate store and you can choose to another one if your security requirements will be higher. Moreover I will never use a System account for a WFC service as the end solution. If a service is running under an user account and you have full access to the machine and administrative rights you will be also able to steal the key. Nevertheless less people without crime energy will be have access to the private key. So I would prefer user certificate store.
Oleg
While I'd tend towards agreeing and prefering not to use a system account... it is still the case that in the majority of cases this service _will_ use the Local System Account
Cocowalla
I don't know your requirements, but there are a principle of minimal rights. You should run WCF under Local System Account only if it is mandatory for your requirements. Only some services which I written last years run under Local System Account. Some from there can run even under Local Service Account. All depends on the requirements.
Oleg
In most cases the service will require full access to the system, including some rights that can only be granted by policy - so in _most_ cases end users will choose the easy option and run under Local System Account. But there will be some that will favour security over ease of installation.
Cocowalla
I have good experience in using CreateFile with FILE_FLAG_BACKUP_SEMANTICS and RegCreateKeyEx with REG_OPTION_BACKUP_RESTORE. If you grant SE_BACKUP_NAME to a user account used for a service you will be able to read/write all file/registry where account directly have no access. If you have an account with SE_DEBUG_NAME privilege you will be able any time with respect of DLL injection (see http://www.codeproject.com/KB/DLL/DLL_Injection_tutorial.aspx) execute any action in context of another process like Winlogon.exe which run under Local System account.
Oleg