2013-07-09 55 views
1

在我需要使用不同密鑰解密文本的情況下,我還需要在後面的代碼中創建有效密鑰。爲什麼TripleDES.Create()。Key對於此算法不是有效大小?

我正在使用此行來生成密鑰。

var key = Encoding.UTF8.GetString(TripleDES.Create().Key); 

但在此方法中不能使用該密鑰。它說「指定的密鑰不是此算法的有效大小」

我該如何解決這種情況?

public class CryptoHelper 
{ 
    public string Encrypt(string toEncrypt, string key) 
    { 
     var toEncryptArray = Encoding.UTF8.GetBytes(toEncrypt); 
     var keyArray = Encoding.UTF8.GetBytes(key); 

     var tdes = new TripleDESCryptoServiceProvider { Key = keyArray, Mode = CipherMode.ECB, Padding = PaddingMode.PKCS7 }; 

     var cTransform = tdes.CreateEncryptor(); 
     var resultArray = cTransform.TransformFinalBlock(toEncryptArray, 0, toEncryptArray.Length); 
     tdes.Clear(); 

     return Convert.ToBase64String(resultArray, 0, resultArray.Length); 
    } 

    public string Decrypt(string cipherString, string key) 
    { 
     var toEncryptArray = Convert.FromBase64String(cipherString.Replace(' ', '+')); 
     var keyArray = Encoding.UTF8.GetBytes(key); 
     var tdes = new TripleDESCryptoServiceProvider { Key = keyArray, Mode = CipherMode.ECB, Padding = PaddingMode.PKCS7 }; 

     var cTransform = tdes.CreateDecryptor(); 
     var resultArray = cTransform.TransformFinalBlock(toEncryptArray, 0, toEncryptArray.Length); 
     tdes.Clear(); 

     return Encoding.UTF8.GetString(resultArray); 
    } 
} 
+2

無法保證通過充當一個有效的UTF-8序列來爲一個密鑰生成的字節可以安全地四捨五入到一個字符串中。您似乎已經意識到**數據**不能在不使用保留所有字節的編碼的情況下被四捨五入 - 例如Base 64--您爲什麼假定密鑰可以? –

+1

@Jodrell - 如果您將不是UTF-8的字節序列解碼爲UTF-8,則可能會得到替換字符。當您對包含替換字符的字符串進行重新編碼時,結果輸出可能會有不同的長度,因爲替換字符的編碼方式與替換字符不同。 –

+0

@Damien_The_Unbeliever,正如你從我的回答中看到的那樣,你是真實的。 – Jodrell

回答

5

如果你寫了一個小測試,你的問題變得很明顯,

var failures = ParallelEnumerable.Range(0, 10000).Count(i => 
    { 
     var keyBefore = TripleDES.Create().Key; 
     var keyAfter = Encoding.UTF8.GetBytes(Encoding.UTF8.GetString(keyBefore)); 
     return !keyBefore.SequenceEqual(keyAfter); 
    }); 

在我的測試,每一個試圖往返失敗。這證實了達米安的評論。

有沒有保證,一鍵生成的字節可以安全地 往返式操作通過充當成一個字符串,就好像他們是一個合法的UTF-8 序列。

keyAfter(幾乎)總是有點擴大,有時加倍。事實上,我無法僥倖得到一個可以改變的密鑰,這可能與避免弱密鑰有關。


但是,如果我嘗試

var failures = ParallelEnumerable.Range(0, 10000).Count(i => 
    { 
     var keyBefore = TripleDES.Create().Key; 
     var keyAfter = Convert.FromBase64String(Convert.ToBase64String(keyBefore)); 
     return !keyBefore.SequenceEqual(keyAfter); 
    }); 

failures總是等於0,符合市場預期。所以,有一個簡單的解決方案。

相關問題