2010-07-11 70 views
0

好吧,在這一點上,我已經想出了我遇到的許多其他問題。現在嘗試解密文件時,我沒有收到任何異常,但是數據沒有正確解密....它在整個操作過程中不會拋出異常,直到我嘗試在解密後再次通過組合框訪問XML文檔。此時出現此錯誤:文件不會正確解密

發生意外的文件結束。以下元素未關閉:帳戶。第12行,位置10. 當我在Web瀏覽器中打開文件時,它只有一個XML節點的一半。發生了什麼?

public partial class Form1 : Form 
{ 
    public string fileName = "passfile.xml"; 
    public DataSet ds = new DataSet("Account List"); 
    public DataTable accounts = new DataTable("Accounts"); 
    public Form1() 
    { 
     InitializeComponent(); 
     accountGroupsBox.Enabled = false; 
     menuStrip1.Enabled = false; 
     button2.Enabled = false; 
     Types type = new Types(); 
     this.accountGroupsBox.Items.AddRange(type.accountTypes); 
     accounts.Columns.AddRange(new DataColumn[] { 
      new DataColumn("Username"), 
      new DataColumn("Password"), 
      new DataColumn("Description")}); 

     dataGridView1.DataSource = accounts; 


    } 

    private void addNewPasswordToolStripMenuItem_Click(object sender, EventArgs e) 
    { 
     Form2 addAccount = new Form2(this); 
     addAccount.Show(); 
    } 

    private void S_Click(object sender, EventArgs e) 
    { //Need to add some code to check for password correctness, for now just unlock the interface 
     accountGroupsBox.Enabled = true; 
     menuStrip1.Enabled = true; 
     button2.Enabled = true; 
     label2.Text = "Interface Unlocked"; 
    } 

    private void accountGroupsBox_SelectedIndexChanged(object sender, EventArgs e) 
    { //Display the accounts on the datagrid 
     accounts.Clear(); 
     XmlDocument doc = new XmlDocument(); 
     doc.Load(fileName); 
     foreach (XmlNode node in doc.GetElementsByTagName("Account")) 
     { 
      if (node["AccountType"].InnerText == accountGroupsBox.SelectedItem.ToString()) 
      { 
       DataRow row = accounts.Rows.Add(
       node["Username"].InnerText, 
       node["Password"].InnerText, 
       node["Description"].InnerText); 
      } 
     } 


    } 
    public void Encrypt() 
    { 
     string temp = Path.GetTempFileName(); 
     string path = System.IO.Path.GetDirectoryName(Application.ExecutablePath); 
     byte[] pword = Encoding.UTF8.GetBytes(textBox1.Text); 
     byte[] hash = SHA256.Create().ComputeHash(pword); 
     byte[] iv = MD5.Create().ComputeHash(pword); 
     byte[] key = hash; 

     using(FileStream fsInput = new FileStream(fileName, FileMode.Open, FileAccess.Read)) 
     using(SymmetricAlgorithm alg = Aes.Create()) 
     using(ICryptoTransform enc = alg.CreateEncryptor(key, iv)) 
     using (FileStream fsOutput = new FileStream(temp, FileMode.Create, FileAccess.Write)) 
     using (CryptoStream cs = new CryptoStream(fsOutput, enc, CryptoStreamMode.Write)) 
     { 
      try 
      { 
       byte[] byteInput = new byte[fsInput.Length - 1]; 
       fsInput.Read(byteInput, 0, byteInput.Length); 
       cs.Write(byteInput, 0, byteInput.Length); 

       FileInfo old = new FileInfo(fileName); 
       FileInfo newer = new FileInfo(temp); 
       old.Delete(); 
       newer.MoveTo(Path.Combine(path, fileName)); 


      } 
      catch (Exception ex) 
      { 
       MessageBox.Show(ex.ToString(), "Encryption Error", MessageBoxButtons.OK); 

      } 
     } 


    } 
    public void Decrypt() 
    { 

     byte[] pword = Encoding.UTF8.GetBytes(textBox1.Text); 
     byte[] hash = SHA256.Create().ComputeHash(pword); 
     byte[] iv = MD5.Create().ComputeHash(pword); 
     byte[] key = hash; 

     using(FileStream fsInput = new FileStream(fileName, FileMode.Open, FileAccess.Read)) 
     using(SymmetricAlgorithm alg = Aes.Create()) 
     using(ICryptoTransform enc = alg.CreateDecryptor(key, iv)) 
     using (CryptoStream cs = new CryptoStream(fsInput, enc, CryptoStreamMode.Read)) 
     { 
      StreamWriter sw = new StreamWriter(temp); 
      sw.Write(new StreamReader(cs).ReadToEnd()); 
      sw.Flush(); 
      sw.Close(); 
     } 
     FileInfo encrypted = new FileInfo(fileName); 
     FileInfo decrypted = new FileInfo(temp); 
     encrypted.Delete(); 
     decrypted.MoveTo(Path.Combine(path, fileName); 
+0

你是指C#文件加密還是.NET文件加密? – 2010-07-12 06:26:18

回答

2

當您調用old.Delete();時,舊文件fileName仍然打開當使用{}塊結束時它將關閉。移動文件刪除並重命名到您的加密方法的末尾。

+0

這很好,謝謝。但是現在我得到了一個無法創建已存在的new.MoveTo()部分異常的文件。我該如何解決? – Stev0 2010-07-12 05:22:40

+0

@ Stev0 - 您可以將更新的代碼和異常的堆棧跟蹤粘貼到pastebin.com或其他東西。我不確定是什麼原因造成的。 – 2010-07-12 12:27:28

+0

這是指向異常詳細信息的pastebin鏈接: http://pastebin.com/rJ5WPhua – Stev0 2010-07-12 23:08:17

0

Delete和MoveTo操作看起來是在打開的文件上執行的。此外,解密方法會打開「文件名」文件兩次。你在哪一行得到拋出的異常?

+0

同樣的事情,上面的答案確定了與加密有關的部分,現在我在解密時會遇到同樣的異常,特別是在Streamwriter sw行期間,我可以更改哪些內容以解決它? – Stev0 2010-07-12 05:33:02

+0

好吧解決它我只是做了同樣的事情作爲加密方法...將輸出到一個臨時文件,然後移動重命名.... – Stev0 2010-07-12 06:03:42

+0

@ Stev0:你的實例化你的StreamWriter的問題是你通過fileName字符串到它,而不是文件流。 – 2010-07-12 12:22:49