Reputation: 21591
I have the need to secure the login credentials to a privileged account such that they can be accessed by a script of some kind under the proper conditions.
The simple answer could be to encrypt them in the app.config, but then they can be accessed by any user and only on the machine it was encrypted on. I need to distribute this config out via Subversion so that the source will be compiled on any available build server and the build script can access the encrypted data. The build users will be known (could be on different domains), but the machine won't be the same every time.
Can certificates be used? Without a CA? Another method?
Would prefer to do this in C#, so that it can be coupled into an MSBuild task. I do not want to write the decrypted data to the filesystem for security.
Thoughts?
Upvotes: 0
Views: 284
Reputation: 2553
Asymetric encryption is what you need.
Here is a link to MSDN documentation for RSA algorithm which will work.
http://msdn.microsoft.com/en-us/library/system.security.cryptography.rsacryptoserviceprovider.aspx
This is the sample they provide at the bottom of the page.
static void Main()
{
try
{
//Create a UnicodeEncoder to convert between byte array and string.
UnicodeEncoding ByteConverter = new UnicodeEncoding();
//Create byte arrays to hold original, encrypted, and decrypted data.
byte[] dataToEncrypt = ByteConverter.GetBytes("Data to Encrypt");
byte[] encryptedData;
byte[] decryptedData;
//Create a new instance of RSACryptoServiceProvider to generate
//public and private key data.
using (RSACryptoServiceProvider RSA = new RSACryptoServiceProvider())
{
//Pass the data to ENCRYPT, the public key information
//(using RSACryptoServiceProvider.ExportParameters(false),
//and a boolean flag specifying no OAEP padding.
encryptedData = RSAEncrypt(dataToEncrypt, RSA.ExportParameters(false), false);
//Pass the data to DECRYPT, the private key information
//(using RSACryptoServiceProvider.ExportParameters(true),
//and a boolean flag specifying no OAEP padding.
decryptedData = RSADecrypt(encryptedData, RSA.ExportParameters(true), false);
//Display the decrypted plaintext to the console.
Console.WriteLine("Decrypted plaintext: {0}", ByteConverter.GetString(decryptedData));
}
}
catch (ArgumentNullException)
{
//Catch this exception in case the encryption did
//not succeed.
Console.WriteLine("Encryption failed.");
}
}
static public byte[] RSAEncrypt(byte[] DataToEncrypt, RSAParameters RSAKeyInfo, bool DoOAEPPadding)
{
try
{
byte[] encryptedData;
//Create a new instance of RSACryptoServiceProvider.
using (RSACryptoServiceProvider RSA = new RSACryptoServiceProvider())
{
//Import the RSA Key information. This only needs
//toinclude the public key information.
RSA.ImportParameters(RSAKeyInfo);
//Encrypt the passed byte array and specify OAEP padding.
//OAEP padding is only available on Microsoft Windows XP or
//later.
encryptedData = RSA.Encrypt(DataToEncrypt, DoOAEPPadding);
}
return encryptedData;
}
//Catch and display a CryptographicException
//to the console.
catch (CryptographicException e)
{
Console.WriteLine(e.Message);
return null;
}
}
static public byte[] RSADecrypt(byte[] DataToDecrypt, RSAParameters RSAKeyInfo, bool DoOAEPPadding)
{
try
{
byte[] decryptedData;
//Create a new instance of RSACryptoServiceProvider.
using (RSACryptoServiceProvider RSA = new RSACryptoServiceProvider())
{
//Import the RSA Key information. This needs
//to include the private key information.
RSA.ImportParameters(RSAKeyInfo);
//Decrypt the passed byte array and specify OAEP padding.
//OAEP padding is only available on Microsoft Windows XP or
//later.
decryptedData = RSA.Decrypt(DataToDecrypt, DoOAEPPadding);
}
return decryptedData;
}
//Catch and display a CryptographicException
//to the console.
catch (CryptographicException e)
{
Console.WriteLine(e.ToString());
return null;
}
}
}
Upvotes: 1
Reputation: 1232
The step of being able to "distribute" a key/encrypted information and allowing certain users to access this regardless of machine is pretty much the same thing as DRM and they still haven't "solved" this problem :)
Anyway I was wondering if this solution may work for you guys?
So basically this leads me to suggest a double prong solution which is a white list of which machines that can access that information, and users who need to be able to run the script can have the key embedded into their profile?
Upvotes: 0