2010-07-15 58 views
0

这是一个代码段I有用于设定masterpassword:加密例外:输入不是一个完整的块

private void button1_Click(object sender, EventArgs e) 
    { 
     string current = textBox1.Text; 
     string newPass = textBox2.Text; 
     string confirmed = textBox3.Text; 
     string massPass = "winxp.pma"; 


     if (File.Exists(massPass)) 
     { 
      byte[] cipertext = File.ReadAllBytes(massPass); 
      string decoded; 
      if(Encryptor.TryDecrypt(current, cipertext, out decoded)) 
      { 
       FileStream fs = new FileStream(massPass, FileMode.Truncate, FileAccess.Write); 
       StreamWriter sw = new StreamWriter(fs, Encoding.UTF8); 
       if(newPass == confirmed) 
       { 
        byte[] newCipher = Encryptor.Encrypt(newPass, newPass); 
        string writeIt = System.Text.Encoding.UTF8.GetString(newCipher); 
        sw.Write(writeIt); 
        sw.Flush(); 
        sw.Close(); 
        fs.Close(); 
        this.Close(); 

       } 
       else 
       { 
        MessageBox.Show("New password do not match.", "Error", MessageBoxButtons.OK); 
       } 

      } 

     } 
     else 
     { 
      FileStream fs = new FileStream(massPass, FileMode.Create, FileAccess.Write); 
      StreamWriter sw = new StreamWriter(fs, Encoding.UTF8); 
      if (newPass == confirmed) 
      { 
       byte[] ciphertext = Encryptor.Encrypt(newPass, newPass); 
       string writeIt = System.Text.Encoding.UTF8.GetString(ciphertext); 
       sw.Write(ciphertext); 
       sw.Flush(); 
       sw.Close(); 
       fs.Close(); 
       this.Close(); 
      } 

回到主窗体上,我使用以下列方式的TryDecrypt方法:

private void S_Click(object sender, EventArgs e) 
    { 
     byte[] ciphertext = File.ReadAllBytes(massPass); 
     string decoded; 

      if (Encryptor.TryDecrypt(textBox1.Text, ciphertext, out decoded)) 
      { 
       accountGroupsBox.Enabled = true; 
       addNewPasswordToolStripMenuItem.Enabled = true; 
       label2.Text = "Interface Unlocked"; 

      } 
      else 
      { 
       MessageBox.Show("Incorrect Master Password.", "Authentication Error", MessageBoxButtons.OK); 
      } 

然而,正如我提到的,它不会返回true ....我打赌它是与我办理其他形式的文件流的方式,但我不明白什么不够发生在引擎盖下,以确定我是否正确地做。

回答

2

您的输入流不完整。为了能够尝试解密它,它必须是一定的大小。确保你的加密过程是正确的。加密数据应该等于或长于您的普通数据。


我在其他网站上的结论是CryptoStream没有机会在输出文件关闭之前完成写入数据。在处理CryptoStream之前,输出流应保持打开状态,以便能够写入密文的其余部分和必要的填充。

我的测试代码:

public static byte[] Encrypt(string password, string plaintext, SymmetricAlgorithm algorithm) 
{ 
    byte[] key, iv; 
    CreateKeyIV(password, out key, out iv); 
    using (MemoryStream encrypted = new MemoryStream()) 
    { 
     using (CryptoStream enc = new CryptoStream(encrypted, algorithm.CreateEncryptor(key, iv), CryptoStreamMode.Write)) 
     using (StreamWriter writer = new StreamWriter(enc)) 
      writer.Write(plaintext); 
     return encrypted.ToArray(); 
    } 
} 
+1

你甚至检查,其他部位的您的其他职位的答复? :) – 2010-07-15 07:44:59

+0

哦,我几天没有检查调试...我认为这是一个相对不活跃的景象。你在那里发布的代码....我想改变内存流为FileStreams为我的目的是正确的? – Stev0 2010-07-15 18:36:19

+0

是的,它通常是。很多人都在寻找经常回答的慷慨少数人的家庭作业帮助(3-4人,包括我自己)。尽管都出于爱。 ;) - 使用内存流将使这个过程更快更安全,因为您不必使用临时文件以及所有可能带来的问题。为了总结我在调试中提到的内容,请确保在接受加密数据之前关闭CryptoStream。 – 2010-07-15 19:21:55