2012-10-22 35 views
0

我在使asp.net C#文件加密/解密过程正常工作时遇到了一些麻烦。我可以将文件上传并加密,但无法解密。文件解密错误:错误数据

我得到的错误:Exception Details: System.Security.Cryptography.CryptographicException: Bad Data.在解密行:

byte[] KeyDecrypted = rsa.Decrypt(KeyEncrypted, false); 

这里是我的加密功能:

private void EncryptFile(string inFile) 
    { 
     RijndaelManaged rjndl = new RijndaelManaged(); 
     rjndl.KeySize = 256; 
     rjndl.BlockSize = 256; 
     rjndl.Mode = CipherMode.CBC; 
     ICryptoTransform transform = rjndl.CreateEncryptor(); 

     byte[] keyEncrypted = rsa.Encrypt(rjndl.Key, false); 

     byte[] LenK = new byte[4]; 
     byte[] LenIV = new byte[4]; 

     int lKey = keyEncrypted.Length; 
     LenK = BitConverter.GetBytes(lKey); 
     int lIV = rjndl.IV.Length; 
     LenIV = BitConverter.GetBytes(lIV); 

     int startFileName = inFile.LastIndexOf("\\") + 1; 
     // Change the file's extension to ".enc" 
     string outFile = EncrFolder + inFile.Substring(startFileName, inFile.LastIndexOf(".") - startFileName) + ".enc"; 

     lblDecryptFileName.Text = outFile; 

     using (FileStream outFs = new FileStream(outFile, FileMode.Create)) 
     { 
      outFs.Write(LenK, 0, 4); 
      outFs.Write(LenIV, 0, 4); 
      outFs.Write(keyEncrypted, 0, lKey); 
      outFs.Write(rjndl.IV, 0, lIV); 

      using (CryptoStream outStreamEncrypted = new CryptoStream(outFs, transform, CryptoStreamMode.Write)) 
      { 
       int count = 0; 
       int offset = 0; 
       int blockSizeBytes = rjndl.BlockSize/8; 
       byte[] data = new byte[blockSizeBytes]; 
       int bytesRead = 0; 
       using (FileStream inFs = new FileStream(inFile, FileMode.Open)) 
       { 
        do 
        { 
         count = inFs.Read(data, 0, blockSizeBytes); 
         offset += count; 
         outStreamEncrypted.Write(data, 0, count); 
         bytesRead += blockSizeBytes; 
        } 
        while (count > 0); 
        inFs.Close(); 
       } 
       outStreamEncrypted.FlushFinalBlock(); 
       outStreamEncrypted.Close(); 
      } 
      outFs.Close(); 
     } 

    } 

这里是哪里发生错误的解密功能。

private void DecryptFile(string inFile) 
    { 

     // Create instance of Rijndael for 
     // symetric decryption of the data. 
     RijndaelManaged rjndl = new RijndaelManaged(); 
     rjndl.KeySize = 256; 
     rjndl.BlockSize = 256; 
     rjndl.Mode = CipherMode.CBC; 
     byte[] LenK = new byte[4]; 
     byte[] LenIV = new byte[4]; 
     string outFile = DecrFolder + inFile.Substring(0, inFile.LastIndexOf(".")) + ".txt"; 

     using (FileStream inFs = new FileStream(EncrFolder + inFile, FileMode.Open)) 
     { 

      inFs.Seek(0, SeekOrigin.Begin); 
      inFs.Seek(0, SeekOrigin.Begin); 
      inFs.Read(LenK, 0, 3); 
      inFs.Seek(4, SeekOrigin.Begin); 
      inFs.Read(LenIV, 0, 3); 

      int lenK = BitConverter.ToInt32(LenK, 0); 
      int lenIV = BitConverter.ToInt32(LenIV, 0); 
      int startC = lenK + lenIV + 8; 
      int lenC = (int)inFs.Length - startC; 

      // Create the byte arrays for 
      // the encrypted Rijndael key, 
      // the IV, and the cipher text. 
      byte[] KeyEncrypted = new byte[lenK]; 
      byte[] IV = new byte[lenIV]; 

      // Extract the key and IV 
      // starting from index 8 
      // after the length values. 
      inFs.Seek(8, SeekOrigin.Begin); 
      inFs.Read(KeyEncrypted, 0, lenK); 
      inFs.Seek(8 + lenK, SeekOrigin.Begin); 
      inFs.Read(IV, 0, lenIV); 
      Directory.CreateDirectory(DecrFolder); 

      byte[] KeyDecrypted = rsa.Decrypt(KeyEncrypted, false); 

      ICryptoTransform transform = rjndl.CreateDecryptor(KeyDecrypted, IV); 

      using (FileStream outFs = new FileStream(outFile, FileMode.Create)) 
      { 

       int count = 0; 
       int offset = 0; 

       int blockSizeBytes = rjndl.BlockSize/8; 
       byte[] data = new byte[blockSizeBytes]; 

       inFs.Seek(startC, SeekOrigin.Begin); 
       using (CryptoStream outStreamDecrypted = new CryptoStream(outFs, transform, CryptoStreamMode.Write)) 
       { 
        do 
        { 
         count = inFs.Read(data, 0, blockSizeBytes); 
         offset += count; 
         outStreamDecrypted.Write(data, 0, count); 

        } 
        while (count > 0); 

        outStreamDecrypted.FlushFinalBlock(); 
        outStreamDecrypted.Close(); 
       } 
       outFs.Close(); 
      } 
      inFs.Close(); 
     } 

    } 

对此的任何帮助将是伟大的!我不是RSA加密专家,并且阅读了很多帖子,但仍然无法提出解决方案。

+0

我还没有看过代码,但只是一个想法..数据是坏的?您是否比较了上传两面的数据以确保其相同? –

+0

粘贴的代码似乎工作正常。错误必须在其他地方,无论是在数据本身还是在rsa cryptor(未显示)的设置中。 – SilverbackNet

+0

Mystere Man - 我试图比较任何一方的数据,但是由于解密端是加密的,除非我误解,否则我看不到这一点。 – SimonSays

回答

1

我终于明白了这一点。当我在那里尝试时,代码在桌面应用程序中运行良好。它只是在我试图编写的asp.net 4 web应用程序中不起作用。问题是RSA对象没有通过会话持续。所以,RSA对象创建好了。该文件加密可以。但是当我去解密文件时,RSA对象不在那里。 System.Security.Cryptography.CryptographicException: Bad Data的错误信息是误导性的,因为这不是真正的问题,数据是好的。

因此,创建密钥和RSA对象时,我用下面的:

rsa = new RSACryptoServiceProvider(cspp); 
Session["rsa"] = rsa; 

接下来,当解密函数被调用我说:

if (rsa == null) 
    rsa = (RSACryptoServiceProvider)Session["rsa"]; 

当然,还有更多的代码围绕这一点也是如此,以防RSA会话没有密钥,但这是我遇到的问题的高级解决方案。

如果有人正在寻找这个让我知道,我可以分享更多的代码。