2013-09-16 81 views
2

假設使用256個密鑰/ IV使用AES加密少量數據。加密的數據可能是已知的。例如:將salt加入要加密的數據?

abcdefghijklmno|axXXyyYY343433553353afsafaadfafdfsafsf|2013-01-01T00:00:00

前兩個部分(如果你打破管道字符數據)很少改變。最後一部分,日期/時間確實發生了變化,但並不經常。我注意到,改變日期而不是消息的第一部分會導致密碼文本始終保持相同,這可能是因爲純文本是以相同的方式開始的。

這是否會打開我對加密算法的任何形式的攻擊?通過將鹽值添加到純文本的開頭,我可以獲得任何收益嗎?

我使用AesManaged類生成IV /密鑰,並加密/解密純文本,如果這有所不同。

+0

請顯示您用於生成密鑰/ IV的代碼。 – Iridium

+0

@Iridium Key/IV是通過使用AesManaged類並調用GenerateIV和GenerateKey方法生成的,但它們都是固定的。下面的答案表明我應該爲每條消息更改IV。 – Andy

回答

4

爲了解決這個問題,通常IV是針對每個超文本隨機生成的,並且預先不加密到加密數據。通過這種方式,每個加密數據都與其他數據不同。

在代碼應該是

string str = "abcdefghijklmno|axXXyyYY343433553353afsafaadfafdfsafsf|2013-01-01T00:00:00"; 
byte[] data = Encoding.UTF8.GetBytes(str); 
byte[] key = new byte[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 }; // Your random key, I hope more random! 

byte[] encrypted; 

// Encrypt 

using (var am = new AesManaged()) 
using (var rng = new RNGCryptoServiceProvider()) 
{ 
    am.Key = key; 

    var iv = new byte[am.BlockSize/8]; 
    rng.GetBytes(iv); 
    am.IV = iv; 

    using (var encryptor = am.CreateEncryptor()) 
    using (var ms = new MemoryStream()) 
    { 
     ms.Write(iv, 0, iv.Length); 

     using (var encStream = new CryptoStream(ms, encryptor, CryptoStreamMode.Write)) 
     { 
      encStream.Write(data, 0, data.Length); 
     } 

     encrypted = ms.ToArray(); 
    } 
} 

// Decrypt 

string str2; 

using (var am = new AesManaged()) 
using (var ms = new MemoryStream(encrypted)) 
{ 
    am.Key = key; 

    var iv = new byte[am.BlockSize/8]; 
    ms.Read(iv, 0, iv.Length); 
    am.IV = iv; 

    using (var decryptor = am.CreateDecryptor()) 
    using (var decStream = new CryptoStream(ms, decryptor, CryptoStreamMode.Read)) 
    using (var ms2 = new MemoryStream()) 
    { 
     decStream.CopyTo(ms2); 

     str2 = Encoding.UTF8.GetString(ms2.GetBuffer(), 0, (int)ms2.Length); 
    } 
} 

注意,在一般IV重用導致加密的弱點。參見例如wiki

對於CBC和CFB,重用IV泄露關於明文的第一個塊的某些信息,和關於由兩個消息共享的任何公共前綴。對於OFB和CTR,重複使用IV完全破壞了安全性。[6]

+0

是否需要將IV寫入流中?因爲你在它上面設置了IV屬性,所以我會假設.Net AES類會照顧到它。如果每封郵件都有其獨特之處,IV是否需要保密,還是像鹽一樣,並假設它會被發現? – Andy

+0

您可以將它寫入流中。它不需要保密。網絡類不會將它寫入流中,因爲在寫入它的位置上沒有固定的標準。 – xanatos

+0

從我之前引用的wiki中可以看出:「初始化矢量與密鑰有不同的安全要求,所以IV通常不需要保密」 – xanatos

-3

AES256應混合256位(32字節)的數據塊中的數據。由於您的文本長度很長(> 32字節),很少發生變化,所以使用加密方法的性能會很差。您可以修復此問題,但只要在前32個字節內更改的情況下,就會使用頻繁更改的明文字符串開始。你可以這樣做,創建一些隨機種子和實際有用的數據。

播種的目的是讓「已知」字符串在加密後不會生成可識別的圖案。這是您將遇到的確切問題,因此您需要爲您的數據提供種子,或者至少在明文開始時使用易失性數據。

編輯: 我看到我有一個否定,並想知道爲什麼。首先,通過性能,我打算提到加密的質量,而不是執行時間。當我意思是鹽時,我不小心說了種子。一個小錯誤,但我明白爲什麼不利。我離開了我的答案,因爲它是解釋(或者試圖解釋)唯一一次經常變化的鹽(或者至少是某些東西)確實需要以供給AES-256的32字節明文塊出現。如果您的加密數據受字典式攻擊(例如密碼)的影響,通常需要進行醃製操作,這對於OP來說似乎不太可能,但您的加密數據不應該是「可預測的」,這就是爲什麼OP應該在前32字節。

+1

糟糕的表現在這裏不應該成爲一個問題,至少在安全之前不應該擔心。重複明文會導致比改變數據更糟的性能(爲什麼要這麼做?),這當然不是真的。術語種子(或播種)通常用於僞隨機數生成器(CSPRNG),而不用於加密算法。使用易失性數據 - 另一個未使用的加密術語 - 對於CBC加密數據來說是不夠的,它必須與隨機無法區分。 –

2

這是IV的主要目的之一。你應該爲你發送的每條消息生成一個隨機的IV(如果你已經這麼做了,你的代碼中必然會出現錯誤)。