The Data Protection API (in Windows 2000 or later) provides methods to securely store secret information (e.g., a cached password) on a local computer. Only the logged-in user can decrypt the protected data (if they also have the key that was used to protect it). In .NET, these APIs are exposed through the ProtectedData class.
On one of our XP test systems, a call to ProtectedData.Protect unexpectedly failed with a CryptographicException that had a very puzzling exception message:
System.Security.Cryptography.CryptographicException: The system cannot
find the file specified.
at System.Security.Cryptography.ProtectedData.Protect(Byte[] userData,
Byte[] optionalEntropy, DataProtectionScope scope)
There is no information provided on which file is required or why it’s missing, or even why protecting data (in memory) requires file system access in the first place. Searching the internet for the error message turned up just a few other programmers who were also experiencing, but no solutions.
Since the ProtectedData class is just a thin wrapper around the Win32
CryptProtectData function, I searched for the underlying Win32
error code, and found the
answer: the
crypto methods read the
HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\User
Shell Folders
registry key; if there are missing values, the methods will
fail. (This makes me think that the methods are incorrectly reading the “User
Shell Folders” key, instead of calling SHGetFolderPath, as Raymond
recommends,
but I haven’t been able to test that yet.)
Posted by Bradley Grainger on September 12, 2009