We have table where we keep user/password and some other data. Each record's password field must be encrypted. We decided to use AesCryptoServiceProvider for encryption and manually created rgbKey for one time. Then encrypted all the user passwords and inserted records into our table where password fields encrypted with our rgbKey.
We have several servers behind load balancer and each server should read these records and can decrypt password field value. At the beginning we placed rgbKey in base64StringFormat into our dll(API) and likewise all servers will be using this API and can decrypt encrypted values.
However, it is very insecure to keep rgbKey in the dll file. We discussed whether to keep our key in DPAPI. At the decryption time, at any our server, we will get our key from DPAPI and successfully decrypt encrypted value.
I thought that I can produce protected key for once in any of the server with current user mode, then save it in our common dll. Each server using common dll, giving this protected key(byte[]) to DPAPI with the same user, can get unprotected key value. However it works only in the machine where it is protected, at the other machines it gives the error : "Key not valid for use in specified state."
My question is how can I protect my permanent rgbKey so that I can access it from all machines? And looking similar test console application below, what is wrong with my approach?
I give a sample code for my test console application:
First of all I run my PDPAPI() function in my local machine:
static void PDPAPI() {
System.Text.UTF8Encoding encoding = new System.Text.UTF8Encoding();
byte[] rgbKey = encoding.GetBytes( "MyRgbKey" );
byte[] protectedData = ProtectedData.Protect( rgbKey, null, DataProtectionScope.CurrentUser );
string base64ProtectedData = Convert.ToBase64String( protectedData );
Console.WriteLine( "base64ProtectedData:{0}", base64ProtectedData );
}
Then hardcodedly add to my UDPAPI() function base64ProtectedData value got from the above execution, rebuild the solution :
static void UDPAPI() {
string base64ProtectedData = "****";
byte[] protectedData = Convert.FromBase64String( base64ProtectedData );
byte[] unProtectedData = ProtectedData.Unprotect( protectedData, null, DataProtectionScope.CurrentUser );
string base64unProtectedData = Convert.ToBase64String( unProtectedData );
Console.WriteLine( "base64unProtectedData:{0}", base64unProtectedData );
}
Now if I run UDPAPI() function in my local machine it successfully unprotect the data, however if I migrate my console application to any other server, and logging in that server with my network user, the console application gives error "Key not valid for use in specified state.".