Jon Skeet said:
Dica said:
thanks ollie, but now i've got a new problem. based on your response, i've
modified the code where i read back the encrypted XML node as follows and
then attempt to decrypt as follows:
sUserName = oXmlReader.ReadString();
byte[] btUserNameCiphered = Convert.FromBase64String(sUserName);
byte[] btUserNameDecrypted = dec.Decrypt(btUserNameCiphered,key); // craps
out here //
this decrypt class is throwing a "Bad Data" error.
Could you post a short but complete program which demonstrates the
problem?
okay, you asked for it. i can't include the entire encryption assembly, but
will post the code that calls it. it's important to note that the decoder
class in the missing assembly does appear to be working fine since i'm able
to encode and then decode again as i've previously mentioned. the problem
appears to be when reading the encoded value in from XML. here's the code
and i'll include a snippet from the decode class where the error is getting
generated below.
using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
using System.Xml;
using System.IO;
using Encryption;
using System.Text;
using Microsoft.Win32;
namespace timeTracker
{
public class userSettings : System.Windows.Forms.Form
{
private System.Windows.Forms.Button cmdSave;
private System.Windows.Forms.TextBox tbUserName;
private System.Windows.Forms.Label lblUserName;
private System.Windows.Forms.Label lblPassword;
private System.Windows.Forms.TextBox tbPassword;
private System.Windows.Forms.Button cmdCancel;
private System.Data.SqlClient.SqlConnection oSqlConnection;
private System.Data.SqlClient.SqlCommand oSqlSelectCommand;
private System.Data.SqlClient.SqlDataReader oReader;
private String STR_FILE_NAME = Application.UserAppDataPath +
"\\timeSheetConfig.xml";
private System.ComponentModel.Container components = null;
public userSettings()
{
InitializeComponent();
getDefaults();
}
protected override void Dispose( bool disposing )
{
if( disposing )
{
if(components != null)
{
components.Dispose();
}
}
base.Dispose( disposing );
}
#region Windows Form Designer generated code
private void InitializeComponent()
{
System.Resources.ResourceManager resources = new
System.Resources.ResourceManager(typeof(userSettings));
this.cmdSave = new System.Windows.Forms.Button();
this.tbUserName = new System.Windows.Forms.TextBox();
this.lblUserName = new System.Windows.Forms.Label();
this.lblPassword = new System.Windows.Forms.Label();
this.tbPassword = new System.Windows.Forms.TextBox();
this.cmdCancel = new System.Windows.Forms.Button();
this.SuspendLayout();
//
// cmdSave
//
this.cmdSave.Location = new System.Drawing.Point(80, 72);
this.cmdSave.Name = "cmdSave";
this.cmdSave.TabIndex = 0;
this.cmdSave.Text = "Save";
this.cmdSave.Click += new System.EventHandler(this.cmdSave_Click);
//
// tbUserName
//
this.tbUserName.Location = new System.Drawing.Point(80, 16);
this.tbUserName.Name = "tbUserName";
this.tbUserName.Size = new System.Drawing.Size(160, 20);
this.tbUserName.TabIndex = 1;
this.tbUserName.Text = "";
//
// lblUserName
//
this.lblUserName.BackColor = System.Drawing.Color.Transparent;
this.lblUserName.Location = new System.Drawing.Point(8, 16);
this.lblUserName.Name = "lblUserName";
this.lblUserName.Size = new System.Drawing.Size(64, 23);
this.lblUserName.TabIndex = 2;
this.lblUserName.Text = "User Name";
//
// lblPassword
//
this.lblPassword.BackColor = System.Drawing.Color.Transparent;
this.lblPassword.Location = new System.Drawing.Point(8, 48);
this.lblPassword.Name = "lblPassword";
this.lblPassword.Size = new System.Drawing.Size(64, 23);
this.lblPassword.TabIndex = 3;
this.lblPassword.Text = "Password";
//
// tbPassword
//
this.tbPassword.Location = new System.Drawing.Point(80, 40);
this.tbPassword.Name = "tbPassword";
this.tbPassword.PasswordChar = '*';
this.tbPassword.Size = new System.Drawing.Size(160, 20);
this.tbPassword.TabIndex = 4;
this.tbPassword.Text = "";
//
// cmdCancel
//
this.cmdCancel.Location = new System.Drawing.Point(155, 72);
this.cmdCancel.Name = "cmdCancel";
this.cmdCancel.TabIndex = 5;
this.cmdCancel.Text = "Cancel";
this.cmdCancel.Click += new System.EventHandler(this.cmdCancel_Click);
//
// userSettings
//
this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
this.BackgroundImage =
((System.Drawing.Image)(resources.GetObject("$this.BackgroundImage")));
this.ClientSize = new System.Drawing.Size(280, 133);
this.Controls.Add(this.cmdCancel);
this.Controls.Add(this.tbPassword);
this.Controls.Add(this.lblPassword);
this.Controls.Add(this.lblUserName);
this.Controls.Add(this.tbUserName);
this.Controls.Add(this.cmdSave);
this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
this.Name = "userSettings";
this.Text = "User Settings";
this.Load += new System.EventHandler(this.userSettings_Load);
this.ResumeLayout(false);
}
#endregion
private void cmdCancel_Click(object sender, System.EventArgs e)
{
this.Dispose();
}
public void getDefaults()
{
String sUserName = "";
String sPassword = "";
FileInfo oFileInfo = new FileInfo(STR_FILE_NAME);
bool bFileExists = oFileInfo.Exists;
if (bFileExists) // config file exists - read the user details values //
{
XmlTextReader oXmlReader = null;
oXmlReader = new XmlTextReader (STR_FILE_NAME);
try
{
while (oXmlReader.Read())
{
if(oXmlReader.NodeType == XmlNodeType.Element)
{
if (oXmlReader.LocalName.Equals("userName"))
{
sUserName = oXmlReader.ReadString();
}
}
}
}
catch(System.Xml.XmlException xmlErr)
{
MessageBox.Show("Error reading configuration file! Error is " + xmlErr,
"Configuration File Error");
}
finally
{
oXmlReader.Close();
}
}
// decrypt the data //
Encryptor enc = new Encryptor(EncryptionAlgorithm.TripleDes);
Decryptor dec = new Decryptor(EncryptionAlgorithm.TripleDes);
byte[] key = Encoding.ASCII.GetBytes("0123456789012345");
dec.IV = enc.IV;
byte[] btUserNameCiphered = Convert.FromBase64String(sUserName);
byte[] btUserNameDecrypted = dec.Decrypt(btUserNameCiphered,key);
System.Console.WriteLine("Converted back from XML: " +
Encoding.ASCII.GetString(btUserNameDecrypted));
enc = null;
dec = null;
tbUserName.Text = sDecryptedUserName;
}
private void cmdSave_Click(object sender, System.EventArgs e)
{
String sUserName = tbUserName.Text;
if (sUserName.Length < 1)
{
MessageBox.Show("Username cannot be blank");
}
else // okay so far - now test the login before saving //
{
oSqlConnection = new System.Data.SqlClient.SqlConnection();
oSqlSelectCommand = new System.Data.SqlClient.SqlCommand();
oSqlConnection.ConnectionString = "neverYouMind";
oSqlConnection.Open();
String sSql = "select id, firstName, lastName from [user] where userName
= '" + sUserName.Replace("'", "''") + "' and password = '" +
sPassword.Replace("'", "''") + "'";
oSqlSelectCommand.CommandText = sSql;
oSqlSelectCommand.CommandType = System.Data.CommandType.Text;
oSqlSelectCommand.Connection = oSqlConnection;
oReader = oSqlSelectCommand.ExecuteReader();
if (oReader.HasRows){ // login okay - save the info //
// encrypt the data //
Encryptor enc = new Encryptor(EncryptionAlgorithm.TripleDes);
byte[] key = Encoding.ASCII.GetBytes("0123456789012345");
byte[] btUserName = Encoding.ASCII.GetBytes(sUserName);
byte[] btUserNameCiphered = enc.Encrypt(btUserName, key);
System.Console.WriteLine("Unencoded userName: " +
Convert.ToBase64String(btUserName) + ". Ciphered userName: " +
Convert.ToBase64String(btUserNameCiphered));
// decrypt the data - i don't normally need to do this here but want to
see if my decoder class is working okay //
Decryptor dec = new Decryptor(EncryptionAlgorithm.TripleDes);
dec.IV = enc.IV;
byte[] btUserNameDecrypted = dec.Decrypt(btUserNameCiphered,key);
System.Console.WriteLine("Decrypted userName: " +
Encoding.ASCII.GetString(btUserNameDecrypted));
enc = null;
dec = null;
// now save info to xml user settings file //
FileInfo oFileInfo = new FileInfo(STR_FILE_NAME);
XmlTextWriter oXmlWriter = null;
using (FileStream stream = oFileInfo.Open(FileMode.OpenOrCreate,
FileAccess.Write))
{
oXmlWriter = new XmlTextWriter(stream, null);
try
{
oXmlWriter.Formatting = Formatting.Indented;
oXmlWriter.Indentation= 6;
oXmlWriter.Namespaces = false;
oXmlWriter.WriteStartDocument();
oXmlWriter.WriteStartElement("", "userDetails", "");
oXmlWriter.WriteStartElement("", "userName", "");
oXmlWriter.WriteString(Convert.ToBase64String(btUserNameCiphered));
oXmlWriter.WriteEndElement();
oXmlWriter.WriteEndElement();
oXmlWriter.Flush();
}
catch(Exception err)
{
Console.WriteLine("Exception: {0}", err.ToString());
}
finally
{
if (oXmlWriter != null)
{
oXmlWriter.Close();
stream.Close();
}
}
}
Form1.bReInitializeLogin = true;
MessageBox.Show("User details saved.", "Success");
this.Dispose();
}
else{
MessageBox.Show("Invalid login. Record not saved. Please try again.",
"Failure");
}
}
}
}
}
here's a snippet from the decoder class where the "Bad Data" message shows
up:
public byte[] Decrypt(byte[] bytesData, byte[] bytesKey)
{
//Set up the memory stream for the decrypted data.
MemoryStream memStreamDecryptedData = new MemoryStream();
//Pass in the initialization vector.
transformer.IV = initVec;
ICryptoTransform transform =
transformer.GetCryptoServiceProvider(bytesKey);
CryptoStream decStream = new CryptoStream(memStreamDecryptedData,
transform,
CryptoStreamMode.Write);
try
{
decStream.Write(bytesData, 0, bytesData.Length);
}
catch(Exception ex)
{
throw new Exception("Error while writing encrypted data to the stream: \n"
+ ex.Message);
}
decStream.FlushFinalBlock();
decStream.Close(); // attempts to call this method and decrypt the XML
data crap out on this line //
// Send the data back.
return memStreamDecryptedData.ToArray();
} //end Decrypt
tks