Lately I’ve had to deal with a couple of issues at work that arose due to a poor understanding of how SecureString works. It is a pretty convenient way to do things, but is hardly a panacea, and I think in-depth understanding of the underlying mechanism is required before making a decision to use it to e.g., store secrets in that form, somewhere. I looked around and there is suprisingly little information comprising this topic, so let me write what I found.
How SecureString works
The short of it is that SecureString is a string that uses DPAPI, or Windows Data Protection in order to secure the underlying data IN MEMORY. What interested me was not so much the implementation details as to how it leverages it, but how DPAPI works itself. In the issues I encountered, the scenario was saving the SecureString to disc, a scenario that was definitely not the intended use, but seems to arise again and again when discussing SecureString’s possibilities.
You see, DPAPI works essentially by using a symmetric key that is derived from a MasterKey. This MasterKey is encrypted using the user’s password, and for security reasons, this MasterKey is also regularly regenerated, but we keep the old MasterKeys to ensure we retain the ability to decrypt. A SecureString has a reference to the ID of the MasterKey used to encrypt it, and DPAPI will use the relevant MasterKey to decrypt it properly.
How SecureString does not work
All fine and good. When we change the password in Windows, we provide the old one, and that is used to decrypt the previous MasterKeys, which are then re-encrypted using the new password. So we retain all of our MasterKeys going forward, and never have to worry about losing that data!
Not quite. In any sort of server environment, it is entirely within the realm of possibility that we will lose the previous password. This scenario may indeed be something central to any orchestration done on the VM. In Azure, for instance, there is a convenient API for forcing the password to a specific value, which can be leveraged to, e.g., regularly rotate the password associated with the administrator account on the machine.
However, this API does not take in the previous password, so the older MasterKeys remain encrypted, unaccessible to the user going forward, rendering the sort of useless error message of
Key not valid for use in specified state. if we try to decrypt any SecureStrings encrypted with those lost MasterKeys! Depending on a user context for encryption of application secrets in this manner is something that should then be avoided.
2017-06-21 00:00 +0000