I am currently trying to implement a C# encryption program for the back ups from an SQL database. The database is running on an SQL Express Server which does not support automatic back-up encryption. I am using a free SQL back up app which creates regular back ups of the database. These are unencrypted, so I attempted to create a program to encrypt them as they come in.
I have a method which looks like this.
private static void FileEncrypt(string inputFile, string password)
{
byte[] salt = GenerateRandomSalt();
FileStream fsCrypt = new FileStream(inputFile ".aes", FileMode.Create);
byte[] passwordBytes = System.Text.Encoding.UTF8.GetBytes(password);
Aes AES = Aes.Create();
AES.KeySize = 256;
AES.BlockSize = 128;
AES.Padding = PaddingMode.PKCS7;
var key = new Rfc2898DeriveBytes(passwordBytes, salt, 50000);
AES.Key = key.GetBytes(AES.KeySize / 8);
AES.IV = key.GetBytes(AES.BlockSize / 8);
AES.Mode = CipherMode.CFB;
fsCrypt.Write(salt, 0, salt.Length);
CryptoStream cs = new CryptoStream(fsCrypt, AES.CreateEncryptor(), CryptoStreamMode.Write);
FileStream fsIn = new FileStream(inputFile, FileMode.Open);
byte[] buffer = new byte[1048576];
int read;
try
{
while ((read = fsIn.Read(buffer, 0, buffer.Length)) > 0)
{
cs.Write(buffer, 0, read);
}
// Close up
fsIn.Close();
}
catch (Exception ex)
{
Console.WriteLine("Error: " ex.Message);
}
finally
{
cs.Close();
fsCrypt.Close();
}
}
The method uses the password provided to create a key and the use it to encrypt the file. I also have a decryption method which also takes in a path and password and reverses the operation. This all works wonderfully if the user provides the password.
The issue arises when I try to automate the process. I can't have the user typing in the password every time a file need encrypting but I do not know how to provide the password to the method otherwise.
I obviously cannot store the plaintext password somewhere to be read. I understand that hashing is usually used to store passwords safely. A hash is created and stored from the user's password and then when the user types in their password a hash is recreated and if it matches the ones stored on the system it authenticates the user. This however, takes me back to a user typing in the password which was what I was trying to avoid.
Ideally I would want the user to provide the password once and then all the files that come in would be encrypted with that password. When the user required one of the files they would again provide the password which would decrypt the file back to its original state.
I am very new to cryptography so I may be misunderstanding some things. I have tired to look around the issue but can't seem to find a solution.
CodePudding user response:
This kind of credentials usually are stored in application configuration (application secrets). Security is managed on the level of operating system - eg. by restricting access to the files for specified users. It is probably the easiest way to do this but also the least secure.
(Windows Only) Another way to store your password securely is to use CredentialManager
to save / read the password.
If you host your application on eg. Azure, you can use Azure Key Vault to store the secrets in secure manner.
Hashing the passwords and storing it in secure manner are two different things in this case.
CodePudding user response:
One option could be to use public-key cryptography. I.e. you would generate a public and private key-pair. The encryption program would generate a random AES key. This key would be encrypted with the public key and stored as part of the data. The rest of the data can then be encrypted using the AES key. The encryption program only need access to the public key, and would have no way for the to decrypt any data once the AES key is overwritten in memory.
The decryption program would work in reverse, using the private key to first decrypt the AES key, and then use said key to decrypt the rest of the data. An potential problem with this process would be to ensure that the private key is accessible in case of a failure. So I would highly recommend testing the restoration process.
See Cryptographic services for more information. Also consider that if an attacker can access your backup server, he likely also has access to the live data. So a backup encryption might have more value if the backups are stored less securely than your live data.