I have a windows application with a configuration file that contains some database passwords. I'd like to encrypt this data in such a way that my application can decrypt the data, but that the administrator of my application (ops team who will need to start/stop the service etc) cannot. Is this possible?
This is possible to an extent, on Windows, using the Windows Data Protection API; more specifically the CryptProtectData function. This function allows you to encrypt data against a user profile or machine, so that only that entity may recover the data.
Your setup would look something like this:
- A dedicated service user is configured for the application.
- A helper application running as that service user encrypts credentials with
dwFlagsset to 0, and stores it on disk or in the registry.
- Application runs as the service user and decrypts credentials on startup, using
- Create a group for application service users which is not also privileged in other ways (e.g. part of the Administrators group)
- Use this technique to allow that group's users to start/stop the service.
- Ensure that the group cannot write/modify the executable file, or any of the DLLs within the application directory, or otherwise cause an arbitrary executable to be run under the context of the application service user. This also means that they should not be able to modify the registry keys and values for the service under
It is important to note that, should the application administrators be able to modify the application binary, or run a program under the context of the application service user, they could simply call
CryptUnprotectData and gain access to the credentials.
If you make these application administrators part of the full administrators group, you are giving them the keys to the kingdom - they can install and run whatever software they like at this point (including kernel-mode code) and will be able to bypass any control you implement. Don't do that if you want to maintain control.