2016-05-29 90 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