Knowledgelover,
Let’s re-visit your original request.
You want to have a means of storing and retrieving secured setup information for your application.
To be persistent, it means either writing something to the registry or to a file (I will make the distinction even though the registry is also a file).
Don't get hung-up on file extensions. There is no standard for "info" files that I am aware of. IOW there is no commonly used association with any particular viewer for a file with this extension.
The easiest approach is to use the Properties | Settings item in the solution explorer.
Expand the Properties tree item in the solution explorer.
Select (double-click) the Settings.settings tree node.
A grid will appear.
I will assume that you want to strore two pieces of information. I will assume the first is named “UserName”, and the second will be “Password”.
In the first available row in the settings grid, enter the name of the variable “UserName”.
Enter a new row and set the name to “Password”.
The settings file will be saved as the name of your executable with the extension of “.config”. Example MyApplication.exe will have a file named MyApplication.exe.config
This config file is your info file. It will contain XML.
In your c# code you can read and write this information.
private void button1_Click(object sender, EventArgs e)
{
string un = Properties.Settings.Default.UserName;
string up = Properties.Settings.Default.Password;
MessageBox.Show(string.Format("UserName={0}\r\nPassword={1}",un,up));
}
private void button2_Click(object sender, EventArgs e)
{
Properties.Settings.Default.UserName = "Test user name";
Properties.Settings.Default.Password = "12345";
Properties.Settings.Default.Save();
}
Nothing special to do.
Now if you also want to save that information as encrypted then you need to do something extra. Below is a full blown Encrypting Decrypting class, and the button events redone to reflect the use of Encrypting and Decrypting the information.
private void button1_Click(object sender, EventArgs e)
{
string un = Properties.Settings.Default.UserName;
string up = Properties.Settings.Default.Password;
MessageBox.Show(string.Format("UserName={0}\r\nPassword={1}"
,EncDec.Decrypt(un,"MySecretPrivatePassword")
,EncDec.Decrypt(up,"MySecretPrivatePassword")
));
}
private void button2_Click(object sender, EventArgs e)
{
string un = EncDec.Encrypt("test user name", "MySecretPrivatePassword");
string up = EncDec.Encrypt("12345", "MySecretPrivatePassword");
Properties.Settings.Default.UserName = un;
Properties.Settings.Default.Password = up;
Properties.Settings.Default.Save();
}
using System.Security.Cryptography;
using System.IO;
public class EncDec
{
/// <summary>
/// Encrypt a byte array into a byte array using a key and an IV
/// </summary>
/// <param name="clearData"></param>
/// <param name="Key"></param>
/// <param name="IV"></param>
/// <returns></returns>
public static byte[] Encrypt(byte[] clearData, byte[] Key, byte[] IV)
{
// Create a MemoryStream that is going to accept the encrypted bytes
MemoryStream ms = new MemoryStream();
// Create a symmetric algorithm.
// We are going to use Rijndael because it is strong and available on all platforms.
// You can use other algorithms, to do so substitute the next line with something like
// TripleDES alg = TripleDES.Create();
Rijndael alg = Rijndael.Create();
alg.Key = Key;
alg.IV = IV;
CryptoStream cs = new CryptoStream(ms, alg.CreateEncryptor(), CryptoStreamMode.Write);
// Write the data and make it do the encryption
cs.Write(clearData, 0, clearData.Length);
// Close the crypto stream (or do FlushFinalBlock).
// This will tell it that we have done our encryption and there is no more data coming in,
// and it is now a good time to apply the padding and finalize the encryption process.
cs.Close();
// Now get the encrypted data from the MemoryStream.
// Some people make a mistake of using GetBuffer() here, which is not the right way.
byte[] encryptedData = ms.ToArray();
return encryptedData;
}
/// <summary>
/// Encrypt a string into a string using a password
/// Uses Encrypt(byte[], byte[], byte[])
/// </summary>
/// <param name="clearText"></param>
/// <param name="Password"></param>
/// <returns></returns>
public static string Encrypt(string clearText, string Password)
{
byte[] clearBytes = System.Text.Encoding.Unicode.GetBytes(clearText);
PasswordDeriveBytes pdb = new PasswordDeriveBytes(Password,
new byte[] { 0x49, 0x76, 0x61, 0x6e, 0x20, 0x4d, 0x65, 0x64, 0x76, 0x65, 0x64, 0x65, 0x76 });
byte[] encryptedData = Encrypt(clearBytes, pdb.GetBytes(32), pdb.GetBytes(16));
return Convert.ToBase64String(encryptedData);
}
/// <summary>
/// Encrypt bytes into bytes using a password
/// Uses Encrypt(byte[], byte[], byte[])
/// </summary>
/// <param name="clearData"></param>
/// <param name="Password"></param>
/// <returns></returns>
public static byte[] Encrypt(byte[] clearData, string Password)
{
PasswordDeriveBytes pdb = new PasswordDeriveBytes(Password,
new byte[] { 0x49, 0x76, 0x61, 0x6e, 0x20, 0x4d, 0x65, 0x64, 0x76, 0x65, 0x64, 0x65, 0x76 });
return Encrypt(clearData, pdb.GetBytes(32), pdb.GetBytes(16));
}
/// <summary>
/// Encrypt a file into another file using a password
/// </summary>
/// <param name="fileIn"></param>
/// <param name="fileOut"></param>
/// <param name="Password"></param>
public static void Encrypt(string fileIn, string fileOut, string Password)
{
// First we are going to open the file streams
FileStream fsIn = new FileStream(fileIn, FileMode.Open, FileAccess.Read);
FileStream fsOut = new FileStream(fileOut, FileMode.OpenOrCreate, FileAccess.Write);
// Then we are going to derive a Key and an IV from the Password and create an algorithm
PasswordDeriveBytes pdb = new PasswordDeriveBytes(Password,
new byte[] { 0x49, 0x76, 0x61, 0x6e, 0x20, 0x4d, 0x65, 0x64, 0x76, 0x65, 0x64, 0x65, 0x76 });
Rijndael alg = Rijndael.Create();
alg.Key = pdb.GetBytes(32);
alg.IV = pdb.GetBytes(16);
CryptoStream cs = new CryptoStream(fsOut, alg.CreateEncryptor(), CryptoStreamMode.Write);
int bufferLen = 4096;
byte[] buffer = new byte[bufferLen];
int bytesRead;
do
{
bytesRead = fsIn.Read(buffer, 0, bufferLen); // read a chunk of data from the input file
cs.Write(buffer, 0, bytesRead); // encrypt it
} while (bytesRead != 0);
cs.Close(); // this will also close the unrelying fsOut stream
fsIn.Close();
}
/// <summary>
/// Decrypt a byte array into a byte array using a key and an IV
/// </summary>
/// <param name="cipherData"></param>
/// <param name="Key"></param>
/// <param name="IV"></param>
/// <returns></returns>
public static byte[] Decrypt(byte[] cipherData, byte[] Key, byte[] IV)
{
MemoryStream ms = new MemoryStream();
Rijndael alg = Rijndael.Create();
alg.Key = Key;
alg.IV = IV;
CryptoStream cs = new CryptoStream(ms, alg.CreateDecryptor(), CryptoStreamMode.Write);
// Write the data and make it do the decryption
cs.Write(cipherData, 0, cipherData.Length);
cs.Close();
byte[] decryptedData = ms.ToArray();
return decryptedData;
}
/// <summary>
/// Decrypt a string into a string using a password
/// Uses Decrypt(byte[], byte[], byte[])
/// </summary>
/// <param name="cipherText"></param>
/// <param name="Password"></param>
/// <returns></returns>
public static string Decrypt(string cipherText, string Password)
{
byte[] cipherBytes = Convert.FromBase64String(cipherText);
PasswordDeriveBytes pdb = new PasswordDeriveBytes(Password,
new byte[] { 0x49, 0x76, 0x61, 0x6e, 0x20, 0x4d, 0x65, 0x64, 0x76, 0x65, 0x64, 0x65, 0x76 });
byte[] decryptedData = Decrypt(cipherBytes, pdb.GetBytes(32), pdb.GetBytes(16));
return System.Text.Encoding.Unicode.GetString(decryptedData);
}
/// <summary>
/// Decrypt bytes into bytes using a password
/// Uses Decrypt(byte[], byte[], byte[])
/// </summary>
/// <param name="cipherData"></param>
/// <param name="Password"></param>
/// <returns></returns>
public static byte[] Decrypt(byte[] cipherData, string Password)
{
// We need to turn the password into Key and IV.
// We are using salt to make it harder to guess our key using a dictionary attack -
// trying to guess a password by enumerating all possible words.
PasswordDeriveBytes pdb = new PasswordDeriveBytes(Password,
new byte[] { 0x49, 0x76, 0x61, 0x6e, 0x20, 0x4d, 0x65, 0x64, 0x76, 0x65, 0x64, 0x65, 0x76 });
return Decrypt(cipherData, pdb.GetBytes(32), pdb.GetBytes(16));
}
/// <summary>
/// Decrypt a file into another file using a password
/// </summary>
/// <param name="fileIn"></param>
/// <param name="fileOut"></param>
/// <param name="Password"></param>
public static void Decrypt(string fileIn, string fileOut, string Password)
{
PasswordDeriveBytes pdb = new PasswordDeriveBytes(Password,
new byte[] { 0x49, 0x76, 0x61, 0x6e, 0x20, 0x4d, 0x65, 0x64, 0x76, 0x65, 0x64, 0x65, 0x76 });
FileStream fsIn = new FileStream(fileIn, FileMode.Open, FileAccess.Read);
FileStream fsOut = new FileStream(fileOut, FileMode.OpenOrCreate, FileAccess.Write);
try
{
Rijndael alg = Rijndael.Create();
alg.Key = pdb.GetBytes(32);
alg.IV = pdb.GetBytes(16);
CryptoStream cs = new CryptoStream(fsOut, alg.CreateDecryptor(), CryptoStreamMode.Write);
try
{
int bufferLen = 4096;
byte[] buffer = new byte[bufferLen];
int bytesRead;
do
{
bytesRead = fsIn.Read(buffer, 0, bufferLen);
cs.Write(buffer, 0, bytesRead);
} while (bytesRead != 0);
}
finally
{
if (cs != null) { cs.Close(); } // this will also close the unrelying fsOut stream
}
}
finally
{
if (fsOut != null) { fsOut.Close(); }
if (fsIn != null) { fsIn.Close(); }
}
}
}
If this solved your problem, or answered your question , please mark this topic as solved.
Note to other readers: This is not an example of how you should store user names and passwords in a file. First you shoud make every attempt to NOT store that kind of information. You would never want to set a hard codedkey as done in this example. There are many other ways to get a key, and encrypting/decrypting.
// Jerry
[email]shawjh@meadowcrk.com[/email]