I would like to securely store a shared secret key on Windows but make this key accessible by applications running under potentially different user accounts. On OSX, the solution is to put the key in the System Keychain with an appropriate ACL to restrict access to the key to only the various applications that require use of the key.
On Windows, secure storage (CryptProtectData() and CryptUnprotectData()) allows me to store the secret, encrypted for a particular user but does not seem to allow restricting access to the key to particular processes. Furthermore, there is no way using CryptProttectData to protect data for access by different users.
It seems my only option is a Windows Service that (1) stores the key data securely using CryptProtectData() and (2) exposes key data via a WCF endpoint, handling authentication/authorization in my service. This seems quite heavy (and error prone to get right). Is this my only option?
Well…you can configure
CryptProtectData()to encrypt so that data can be decrypted/accessed by different users by specifying theCRYPTPROTECT_LOCAL_MACHINEflag when you do the encrypt; this will allow any user account on the same computer to decrypt the data usingCryptUnprotectData().As to specific-application(s) vs specific-users, there is not a straightforward way within Windows to do this. Windows’ security model is based on using user accounts to control access to resources, so you’re really left with this.
I don’t know what usecases you have, but you could consider running the applications that need access to this data under one common user account (use the run-as capability) and then restrict access to the protected data to that one user account.