2010-03-30 44 views
2

看來我的代碼添加6個字節加密解密後的結果文件名爲.. 我嘗試它放在一個MKV文件.. 請幫助我的三重DES包裝器有什麼問題?

這裏是我的代碼

class TripleDESCryptoService : IEncryptor, IDecryptor 
{ 
    public void Encrypt(string inputFileName, string outputFileName, string key) 
    { 
     EncryptFile(inputFileName, outputFileName, key); 
    } 

    public void Decrypt(string inputFileName, string outputFileName, string key) 
    { 
     DecryptFile(inputFileName, outputFileName, key); 
    } 

    static void EncryptFile(string inputFileName, string outputFileName, string sKey) 
    { 
     var outFile = new FileStream(outputFileName, FileMode.OpenOrCreate, FileAccess.ReadWrite); 

     // The chryptographic service provider we're going to use 
     var cryptoAlgorithm = new TripleDESCryptoServiceProvider(); 
     SetKeys(cryptoAlgorithm, sKey); 

     // This object links data streams to cryptographic values 
     var cryptoStream = new CryptoStream(outFile, cryptoAlgorithm.CreateEncryptor(), CryptoStreamMode.Write); 

     // This stream writer will write the new file 
     var encryptionStream = new BinaryWriter(cryptoStream); 

     // This stream reader will read the file to encrypt 
     var inFile = new FileStream(inputFileName, FileMode.Open, FileAccess.Read); 
     var readwe = new BinaryReader(inFile); 

     // Loop through the file to encrypt, line by line 
     var date = readwe.ReadBytes((int)readwe.BaseStream.Length); 


     // Write to the encryption stream 
     encryptionStream.Write(date); 


     // Wrap things up 
     inFile.Close(); 
     encryptionStream.Flush(); 
     encryptionStream.Close(); 
    } 

    private static void SetKeys(SymmetricAlgorithm algorithm, string key) 
    { 
     var keyAsBytes = Encoding.ASCII.GetBytes(key); 
     algorithm.IV = keyAsBytes.Take(algorithm.IV.Length).ToArray(); 
     algorithm.Key = keyAsBytes.Take(algorithm.Key.Length).ToArray(); 
    } 

    static void DecryptFile(string inputFilename, string outputFilename, string sKey) 
    { 
     // The encrypted file 
     var inFile = File.OpenRead(inputFilename); 

     // The decrypted file 
     var outFile = new FileStream(outputFilename, FileMode.OpenOrCreate, FileAccess.ReadWrite); 

     // Prepare the encryption algorithm and read the key from the key file 
     var cryptAlgorithm = new TripleDESCryptoServiceProvider(); 

     SetKeys(cryptAlgorithm, sKey); 

     // The cryptographic stream takes in the encrypted file 
     var encryptionStream = new CryptoStream(inFile, cryptAlgorithm.CreateDecryptor(), CryptoStreamMode.Read); 

     // Write the new unecrypted file 
     var cleanStreamReader = new BinaryReader(encryptionStream); 
     var cleanStreamWriter = new BinaryWriter(outFile); 
     cleanStreamWriter.Write(cleanStreamReader.ReadBytes((int)inFile.Length)); 
     cleanStreamWriter.Close(); 
     outFile.Close(); 
     cleanStreamReader.Close(); 
    } 
} 

回答

2

您的代碼不會添加六個字節,3DES會四捨五入至整個塊大小。這是分組密碼的工作原理。您只能在得到的密文中看到它,而不能在解密的明文中看到。

同樣沒有必要擔心,分組密碼必須將明文填充到下一個塊大小,然後才能加密明文。當你解密密文時,填充被刪除。

此外,我做了一個快速代碼審查,並且在代碼中出現錯誤 - 您對IV和密鑰使用相同的密鑰,而且您確實應該使用不同的數據。所以我會將另一個參數添加到DecryptFile(),EncryptFile()和SetKeys()以允許使用不同的IV。

+0

什麼是這個IV,和它們不一樣導致大小不一樣,IV是8個字節,關鍵是24個字節.. 解密文件確實有額外的6個字節,我應該擔心和切斷它嗎? – 2010-03-30 16:55:58

+0

初始化矢量 - 它用於某些分組密碼模式,例如密碼分組鏈接(CBC) - 不必太擔心它!只要確保它與密鑰不一樣 - 這意味着完全不同,使用一個單獨的隨機數字而不是密鑰。 因此,我測試代碼的唯一更改是刪除IEncryptor和IDecryptor,因爲它們不在.NET Framework中 - 它們是什麼? – 2010-03-30 19:44:02

0

我瞥了一下代碼,發現沒有問題,但我對你使用的類不太熟悉,所以我可能是錯的。相反,我會給出一些適用於任何錯誤的一般建議:

嘗試追捕問題。在許多代碼行中很難找到錯誤。創建顯示錯誤行爲的最短代碼。

例如,嘗試將字符串寫入輸出流。尺寸是否正確?

  • 如果不是,您幾乎發現問題 - 文件寫入出了問題,加密的東西與問題無關。
  • 如果是,請繼續以小步驟添加功能,直到發現問題。

這是一種標準的調試技術,非常有幫助,我建議在每次遇到問題時都使用它。

除此之外,請儘量保持乾淨的啓動條件,即確保寫入的文件已被刪除。在不同的輸入上嘗試你的代碼,看看它是否失敗,每次都有完全相同的結果,或者如果有差異。

編輯:

根據其他的響應,64位塊是造成你的麻煩。通過前面介紹的想法,您可以輕鬆排除許多其他因素,直到只剩下加密本身。

然後你可以問「爲什麼TripeDES將7個字節添加到輸入中?」這會比「我的三重DES包裝器出了什麼問題?」這個問題更清晰。 - 你肯定會在一分鐘之內得到這個簡單問題的答案!

0

Tiple-DES是64位分組密碼。不分析你的代碼,我的猜測是你的數據不是64位對齊的,並且它已經被填充了default PKCS7 mode

0

我不知道使用哪種加密模式,但ECB和CBC模式在最後一個塊末尾添加填充位,以將其大小增加到64位。也許這就是你的字節從哪裏來的?

+0

如果我將使用另一種模式,它不會發生? – 2010-03-30 17:39:33