C# 按位&;NET框架方法中的运算符

C# 按位&;NET框架方法中的运算符,c#,.net,c#-4.0,C#,.net,C# 4.0,我在.NET framework类中发现了此方法,它使用按位& 要与字节数组进行比较的运算符: 我认为这个功能不是最优的。 例如,我们有两个字符串: 生活 生活 比较两个字符串时,第三个字符不同。 因此,当将二者转换为字节数组时,第三个字节将不同,并且 因此,布尔变量标志将为false,并且在方法完成之前将为false 我想在这句话后面说: flag = flag & a[i] == b[i]; if(flag==false)return false; 以防止进一步的循环执行。 那么,

我在.NET framework类中发现了此方法,它使用按位
&
要与字节数组进行比较的运算符:

我认为这个功能不是最优的。 例如,我们有两个字符串:

  • 生活
  • 生活
  • 比较两个字符串时,第三个字符不同。 因此,当将二者转换为字节数组时,第三个字节将不同,并且 因此,布尔变量标志将为false,并且在方法完成之前将为false

    我想在这句话后面说:

    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;
    }
    
    public static bool AreByteArraysEqual(字节[]a,字节[]b)
    {
    如果(a==null | | b==null | |(int)a.Length!=(int)b.Length)
    {
    返回false;
    }
    布尔标志=真;
    对于(int i=0;i<(int)a.Length;i++)
    {
    flag=flag&a[i]==b[i];
    }
    返回标志;
    }
    

    保存实现的类位于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;
    }
    }
    }
    
    使用系统;
    使用System.Collections.Generic;
    使用System.IO;
    使用System.Security.Cryptography;
    命名空间System.Web.Helpers
    {
    内部静态类CryptoUtil
    {
    公共静态bool AreByteArraysEqual(字节[]a,字节[]b)
    {
    如果(a==null | | b==null | |(int)a.Length!=(int)b.Length)
    {
    返回false;
    }
    布尔标志=真;
    对于(int i=0;i<(int)a.Length;i++)
    {
    flag=flag&a[i]==b[i];
    }
    返回标志;
    }
    公共静态字节[]计算HA256(IList参数)
    {
    字节[]numArray;
    使用(MemoryStream MemoryStream=new MemoryStream())
    {
    使用(BinaryWriter BinaryWriter=新的BinaryWriter(memoryStream))
    {
    foreach(参数中的字符串参数)
    {
    写入(参数);
    }
    binaryWriter.Flush();
    使用(SHA256Cng SHA256Cng=新SHA256Cng())
    {
    字节[]numArray1=sHA256Cng.ComputeHash(memoryStream.GetBuffer(),0,选中((int)memoryStream.Length));
    努马拉伊=努马拉伊1;
    }
    }
    }
    返回努马拉;
    }
    }
    }
    
    您的代码看起来像反编译器的输出。当反编译器的输出可用时,不要查看它。它可能有相关的意见,并在这里:

    // 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所需的时间取决于初始字节的匹配数量。通常这不是问题。对于这种方法,因为它允许调用者获取数据(通过不断尝试直到第一个字节正确,然后不断尝试直到第二个字节正确,依此类推),这意味着保持秘密。

    您在哪里找到这种实现的?为什么要从问题中删除它?它是CryptoUtil类中的一个比较方法。这很有道理……哦,等等——这看起来像是反编译器的输出。好了,现在您知道如何查看实际的源代码了。:)@纳斯雷丁是的,它确实解释了原因。OP的改进意味着可以使用定时攻击来确定匹配的字节数。这就是评论的全部内容。除了这个答案,还有