Search code examples
c#windowscryptographycertificatex509

Where to store X509 certificate for Windows service?


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


Solution

  • 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.