2011-08-11 48 views
0

我有一个客户端/服务器应用程序。服务器和客户端通信已加密。服务器发送加密的消息给客户端和客户端解密消息并获取它。与“客户”消息相同。如果我向客户端发送大数据或客户端向服务器发送大数据,“我得到要解密的数据的长度无效”错误。如果发送数据的长度很小,没有问题。数据长度的加密或解密有没有限制?我的“解密数据的长度无效”错误

这里是我的代码:

static byte[] Encrypt(byte[] plaintext, byte[] key, byte[] IV) 
    { 
     RijndaelManaged myRijndael = new RijndaelManaged(); 
     myRijndael.Padding = PaddingMode.PKCS7; 
     ICryptoTransform encryptor = myRijndael.CreateEncryptor(key, IV); 
     MemoryStream msEncrypt = new MemoryStream(); 
     CryptoStream csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write); 
     csEncrypt.Write(plaintext, 0, plaintext.Length); 
     csEncrypt.FlushFinalBlock(); 

     return msEncrypt.ToArray(); 

    } 


    public static string Encrypt(string plainText, string password) 
    { 

     byte[] byteDizi = Encoding.Unicode.GetBytes(plaintext); 


     PasswordDeriveBytes pdb = new PasswordDeriveBytes(password, 
                  new byte[] {0x49, 0x76, 0x61, 0x6e, 0x20, 0x4d, 
                     0x65, 0x64, 0x76, 0x65, 0x64, 0x65, 0x76}); 


     byte[] sifreliV = Encrypt(byteDizi, 
      pdb.GetBytes(32), pdb.GetBytes(16)); 
     return Convert.ToBase64String(sifreliV); 

    } 


    // Dekriptolama bir parola ve IV kullanarak 

    static byte[] Decrypt(byte[] encryptedData, 
          byte[] Key, byte[] IV) 
    { 
     RijndaelManaged myRijndael = new RijndaelManaged(); 
     myRijndael.Padding = PaddingMode.PKCS7; 
     ICryptoTransform decryptor = myRijndael.CreateDecryptor(Key, IV); 
     MemoryStream msDecrypt = new MemoryStream(encryptedData); 
     CryptoStream csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read); 
     byte[] fromEncrypt = new byte[encryptedData.Length]; 
     csDecrypt.Read(fromEncrypt, 0, fromEncrypt.Length); 

     return fromEncrypt; 

    } 


    public static string Decrypt(string encryptedData, string password) 
    { 

     byte[] encryptedByte = Convert.FromBase64String(encryptedData); 

     PasswordDeriveBytes pdb = new PasswordDeriveBytes(password, 
                  new byte[] {0x49, 0x76, 0x61, 0x6e, 0x20, 0x4d, 0x65, 
                     0x64, 0x76, 0x65, 0x64, 0x65, 0x76}); 

     byte[] DecryptedData = Decrypt(encryptedByte, 
      pdb.GetBytes(32), pdb.GetBytes(16)); 

     return Encoding.Unicode.GetString(DecryptedData); 
    } 
} 
+1

在你的加密方法中,记录byte []'数组和Base64'String'的长度。在你的解密方法中,对传入的Base64'String'和生成的'byte []'数组的长度做一个类似的记录。这些匹配是否正确?特别是对于你说的大文件造成问题。 – rossum

回答

0

其他人所说的,我认为这将有助于建议;我不会立即发现您发布的代码会引起您所描述的行为。

要提的是,目前这个实现一些严重的安全问题:

  1. 密码盐是不特定的密码。最好使用密码将salt存储在数据库中。每个密码都应该有一个唯一的随机盐。这样,如果有人发现一个密码散列的密码,他们将不知道其他用户帐户是否具有相同的密码。

  2. 初始化向量(“IV”)来自密码,就像密钥一样。这意味着具有相同密码的用户所做的每个加密将具有相同的IV。 IVs应该永不被重新使用。 http://en.wikipedia.org/wiki/Initialization_vector#Properties指出IV必须是独特且不可预测的。使用RNGCryptoServiceProvider生成随机IV。

    通常我喜欢在我的加密函数中生成随机IV。然后,我将IV添加到加密的消息中。解密函数从加密消息的开始处剥离IV以初始化解密类,然后解密其余的字节。

    其原因是两个以相同明文(例如,普通头结构)开头且用相同密钥加密的消息在开始时将具有相同的密文。攻击者可以使用它来发现密钥。

现代密码学只有在所有细节都完美的情况下才能很好地工作。否则,即使很小的实施问题也可能导致其迅速崩溃,并带来严重的安全问题 - 而且没有人会注意到它被破坏。获取你的工作,然后执行这些更改。

相关问题