2016-05-29 75 views
0

運營商,我發現這個方法在.NET框架類,它採用了按位& 運營商來比較字節數組:按位與在.NET框架的方法

我覺得這個功能是不是最佳的。 例如,我們有兩個字符串:

  1. 現場
  2. 生活比較兩個字符串時

第三個字符是不同的。 因此,當將兩者轉換爲字節數組時,第三個字節將會不同,因此布爾型變量標誌將爲假,並且在方法結束之前將爲假。

我會把這一行的後面:

flag = flag & a[i] == b[i]; 
if(flag==false)return false; 

,以防止進一步的循環執行。 那麼爲什麼現在這個實施呢?

public static bool AreByteArraysEqual(byte[] a, byte[] b) 
{ 
    if (a == null || b == null || (int)a.Length != (int)b.Length) 
    { 
     return false; 
    } 
    bool flag = true; 
    for (int i = 0; i < (int)a.Length; i++) 
    { 
     flag = flag & a[i] == b[i]; 
    } 
    return flag; 
} 

enter image description here

保持執行駐留在System.Web.WebPages.dll類,版本= 3.0.0.0命名空間System.Web.Helpers

using System; 
using System.Collections.Generic; 
using System.IO; 
using System.Security.Cryptography; 

namespace System.Web.Helpers 
{ 
internal static class CryptoUtil 
{ 
public static bool AreByteArraysEqual(byte[] a, byte[] b) 
{ 
    if (a == null || b == null || (int)a.Length != (int)b.Length) 
    { 
     return false; 
    } 
    bool flag = true; 
    for (int i = 0; i < (int)a.Length; i++) 
    { 
     flag = flag & a[i] == b[i]; 
    } 
    return flag; 
} 

public static byte[] ComputeSHA256(IList<string> parameters) 
{ 
    byte[] numArray; 
    using (MemoryStream memoryStream = new MemoryStream()) 
    { 
     using (BinaryWriter binaryWriter = new BinaryWriter(memoryStream)) 
     { 
      foreach (string parameter in parameters) 
      { 
       binaryWriter.Write(parameter); 
      } 
      binaryWriter.Flush(); 
      using (SHA256Cng sHA256Cng = new SHA256Cng()) 
      { 
       byte[] numArray1 = sHA256Cng.ComputeHash(memoryStream.GetBuffer(), 0, checked((int)memoryStream.Length)); 
       numArray = numArray1; 
      } 
     } 
    } 
    return numArray; 
} 
} 
} 
+1

你從哪裏找到這個實現? –

+0

你是對的,你的建議允許提前終止循環,並且是一種改進。但是,您提到的'&'運算符是_logical_,而不是_bitwise_和。此外,整個方法可以用Linq擴展方法'SequenceEqual'取代,該方法記錄在[這裏](https://msdn.microsoft.com/en-us/library/bb348567%28v=vs.100%29.aspx )。 – Codor

+9

[這個方法的上面有一個註釋,它正確地解釋了這個點已經是什麼了。](https://github.com/mono/aspnetwebstack/blob/master/src/System.Web.WebPages/Helpers/CryptoUtil.cs)你爲什麼從你的問題中刪除它? – hvd

回答

7

你的代碼看起來像一個反編譯器的輸出。當the actual source code可用時,不要查看反編譯器的輸出。它可能有相關的意見,並在這裏所做的:

// This method is specially written to take the same amount of time 
// regardless of where 'a' and 'b' differ. Please do not optimize it. 
public static bool AreByteArraysEqual(byte[] a, byte[] b) 
... 

你做將意味着評估AreByteArraysEqual爲兩個相等長度的字節數組所需的時間取決於有多少初始字節匹配的改進。通常這不是問題。對於這種方法,它是因爲它允許調用者獲取數據(通過不斷嘗試,直到第一個字節是正確的,然後不斷嘗試,直到第二個字節是正確的,依此類推),這意味着保密。

+1

+1。除了這個答案這裏[維基百科關於這個問題的文章](https://en.wikipedia.org/wiki/Timing_attack) – Nasreddine