2012-10-22 55 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會話沒有密鑰,但這是我遇到的問題的高級解決方案。

如果有人正在尋找這個讓我知道,我可以分享更多的代碼。