The requirement here is simple to encrypt and decrypt only by the logged-in user context. Details go below.
- If some other user logged into the system they should not access it by decrypting the data.
- If the data is in a file and someone gets that file, they should not be able to decrypt
- The user doesn't need to remember one more password. It should work if they logged on to the machine.
- If the machine crashes and the user gets a new machine in the same domain, it's ok to lose the data.
Approach 1 - Generate a random key and keep it in the user profile
Every user has their own area in the system. One promising area is c:\users\<user id>\ folder. We can hold generated encryption key there and use it for a particular user. But that is not safe as the key can be accessed if someone mounts the hard disk in another machine. There are more chances that the key may be leaked.
This is not a dependable approach.
Approach 2 - Use DPAPI - Data Protection API
This is another OS-level feature to encrypt and decrypt based on the user or machine. The code goes as below.
byte[] unprotectedBytes = Encoding.UTF8.GetBytes(unprotectedText);
byte[] protectedBytes = ProtectedData.Protect(unprotectedBytes, null, DataProtectionScope.CurrentUser);
Currently, the API is accepting the byte array as input and gives the encrypted data also as a byte array. If the input is a string, it needs to be converted to a byte[]. The second parameter to Protect() got a null as the goal of this post is to introduce the API. Not to go deep to the scenarios.
Decryption API is also the ProtectedData class. The code is below.
var unprotectedBytes = ProtectedData.Unprotect(protectedBytes, null, DataProtectionScope.CurrentUser);
string unprotectedText = Encoding.UTF8.GetString(unprotectedBytes);
Hope the decryption code is clear once the encryption is understood.
Working sample
It is in GitHub. Feel free to add comments or raise issues. PRs also welcome.
No comments:
Post a Comment