Encryption

隨機存取流密碼

  • November 7, 2015

前段時間,我在一個寵物項目中為一種數據庫引擎工作。而且我考慮過用加密來保護磁碟中的數據..並且由於主要程式碼已經開發..我有一些要求..

  • 一個簡單的流類,我可以掛鉤而不是我的文件流
  • 支持隨機訪問(在隨機位置讀/寫)
  • 能夠在任何字節位置工作(因為數據可能未對齊)
  • 僅加密/解密請求的數據,而不是所有文件,(因為文件可能有幾 MB)
  • 快速加密/解密,因為這是針對數據庫系統的

我在網上沒有找到有關此的資訊或此類程式碼的實現。普通流密碼不支持隨機訪問/查找,分組密碼要求數據對齊並固定在塊中。所以我考慮開發自己的。我知道開發自己的加密總是一個糟糕的選擇..但這是一種理論練習..

所以我想向您展示程式碼..只是從安全的角度來看我有多遠

首先,使用密碼初始化流。但該密碼本身不用於加密。它被用作種子來打亂一個包含 256 個值的數組,以希望增加密鑰空間

public CipherStream(String sKey,Stream oStream) 
{
   _oStream = oStream;
   //initialize key space
   _oVector = new byte[256];
   for(int i = 0; i <= 255; i++)
   _oVector[i] = (byte)i;
   //shuffle the keyspace
   for (int i = 0; i <= 255; i++)//shuffle the box
   {
       //shuffle this item with other
       //other is chosen by char(i) of password
       //and the currently shuffling vector(I)
       // this means that even repeating passwords 'aaaaaa' will produce random results
       int j = ((sKey[i % sKey.Length]) + _oVector[i]) % 256;
       byte cTemp = _oVector[i];
       _oVector[i] = _oVector[j];
       _oVector[j] = cTemp;
   }
}

在此之後,我們所要做的就是為我們試圖讀/寫的位置選擇密碼字節。在我的實現中,我使用了 xor,我知道這不是最安全的。但這是可以改變的不是算法的核心..

public override void Write(byte[] buffer, int offset, int count)
{
   long nPosition = this.Position;
   for (int i = offset; i < count; i++)
   {
       byte oPlain = buffer[i];
       byte nKey = GetKey(nPosition);
       byte oCypher = (byte)(oPlain ^ nKey);

       buffer[i] = oCypher;

       nPosition++;
   }
   _oStream.Write(buffer, offset, count);
}

字節的“密鑰”是根據我們嘗試訪問的位置從密鑰向量中選擇的。進行計算以便沒有重複,並且選擇的值盡可能隨機

private byte GetKey(long nPosition) 
{
   byte nOffset = _oVector[nPosition % _oVector.Length];
   byte nOffset2 = _oVector[(nPosition / (nOffset + 1)) % _oVector.Length];

   int nDif = nOffset - nOffset2;
   if (nDif < 0)
       nDif += 255;
   byte nKey = (Byte)(nDif % 256);

   return nKey;
}

我確實嘗試將流渲染為點陣圖..只是確保沒有明顯的模式..並在那裡做了一些微調..看起來沒問題..

我能描述的最好的算法是一個“確定性可預測的偽隨機生成器”,我可以問“給我第 n 個隨機數”,種子是一個 2048 位向量,用密碼隨機初始化。

我離解決方案還有多遠?這完全不安全嗎?或者甚至沒有嘗試的意義,因為這個“隨機訪問流”問題沒有解決方案?

這個想法

‘確定性可預測的偽隨機生成器’,我可以問’給我第 n 個隨機數’

是已知的,並且有一些像這樣工作的流密碼(如分組密碼的 CTR 模式,或Salsa /ChaCha 流密碼系列)。通常它們不會產生單個字節,而是一些更大的連續密鑰流字節塊,如果您沒有要加密的單個字節,效率會更高,並且(如 user4982 的回答所述)不會限制您,因為您不必使用所有這些密鑰流字節來加密/解密您的數據。

我不會查看您的特定密碼(對我來說程式碼級別太多了),但它可能不是一個安全的密碼。

這個想法本身(即使使用完全安全的流密碼實現)在用於隨機訪問文件加密時存在問題:您將(在幾個時間點)使用相同的密鑰流加密不同的數據,然後如果潛在的攻擊者可以在不同的時間點查看您的加密文件,則會導致兩次填充問題。

您需要使用新的初始化向量重新加密較大的塊以避免這種情況。

引用自:https://crypto.stackexchange.com/questions/11504