代码之家  ›  专栏  ›  技术社区  ›  TheCodeJunkie

CNG、CryptoServiceProvider和HashAlgorithm的托管实现

  •  19
  • TheCodeJunkie  · 技术社区  · 17 年前

    因此,我想知道散列算法的各种实现之间是否有任何主要差异,以SHA系列算法为例。它们每个都有3个实现,1个在托管代码中,2个围绕不同本机加密API的包装器,但是使用它们之间有什么主要区别吗?我可以想象包装器版本可以有更高的性能,因为它是在本机代码中执行的,但是surley hey都需要执行完全相同的计算,从而提供相同的输出,即hey是可交换的。这是正确的吗?

    例如,SHA512CNG不能用于XP SP2(文档错误),但SHA512MANAGED可以。


    @马克西姆-谢谢,但不是我想要的。我在问,使用给定哈希算法的Managed/CryptoServiceProvider/CNG实现是否有任何区别,除了可能的性能之外。使用.NET3.5,您可以通过三种实现获得所有哈希算法,因此

    SHA512管理 SHA512CryptoServiceProvider

    后两个是本机API的包装器。例如,所有SHAXX实现都是如此。

    4 回复  |  直到 13 年前
        1
  •  18
  •   Eric Rosenberger    17 年前

    一个区别是本地版本(至少其中一些)是经过FIPS认证的(即美国政府批准的),而托管版本则不是。如果您的代码恰好在配置为“仅限FIPS”的Windows计算机上运行,则尝试使用托管版本将失败。

    大多数Windows计算机都不是以这种方式配置的,但如果您部署到政府或国防导向(或其他高度安全)环境,则可能会遇到这种情况。

    看见 http://blogs.msdn.com/shawnfa/archive/2005/05/16/417975.aspx .

        2
  •  4
  •   Joe Basirico    17 年前

    Cng版本应该会快一点,但我只是写了一个比较每个版本速度的小程序。(我有一位客户询问MD5与SHA1的性能特征)

    CalculateHash(1, 1024, new SHA1CryptoServiceProvider());
    
    static long CalculateHash(UInt64 repetitions, UInt64 size, HashAlgorithm engine)
        {
            RandomNumberGenerator rng = RandomNumberGenerator.Create();
    
            byte[][] goo = new byte[repetitions][];
            for (UInt64 i = 0; i < repetitions; i++)
            {
                goo[i] = new byte[size];
                rng.GetBytes(goo[i]);
            }
    
            DateTime start = DateTime.Now;
            for (UInt64 i = 0; i < repetitions; i++)
            {
                engine.ComputeHash(goo[i]);
            }
            return DateTime.Now.Subtract(start).Ticks;
        }
    

    int loops = 32;
            UInt64 reps = 1;
    
            int width = 20;
            Console.WriteLine("Loop#".PadRight(6) +
                    "MD5".PadRight(width) +
                    "SHA1".PadRight(width) +
                    "SHA1Cng".PadRight(width) +
                    "SHA256".PadRight(width) +
                    "SHA256Cng".PadRight(width));
    
            for (int i = 0; i < loops; i++)
            {
                UInt64 size = (UInt64)Math.Pow((double)2, (double)i);
    
                Console.WriteLine((i + 1).ToString().PadRight(6) +
                    CalculateHash(reps, size, new MD5CryptoServiceProvider()).ToString().PadRight(width) +
                    CalculateHash(reps, size, new SHA1CryptoServiceProvider()).ToString().PadRight(width) +
                    CalculateHash(reps, size, new SHA1Cng() ).ToString().PadRight(width) +
                    CalculateHash(reps, size, new SHA256CryptoServiceProvider()).ToString().PadRight(width) +
                    CalculateHash(reps, size, new SHA256Cng()).ToString().PadRight(width));
            }
    
    Loop# MD5         SHA1        SHA1Cng     SHA256      SHA256Cng
    1     50210       0           0           0           0
    2     0           0           0           0           0
    3     0           0           0           0           0
    4     0           0           0           0           0
    5     0           0           0           0           0
    6     0           0           0           0           0
    7     0           0           0           0           0
    8     0           0           0           0           0
    9     0           0           0           0           0
    10    0           0           10042       0           0
    11    0           0           0           0           0
    12    0           0           0           0           0
    13    0           0           0           0           0
    14    0           0           0           0           0
    15    10042       0           0           10042       10042
    16    10042       0           0           0           0
    17    0           0           0           10042       10042
    18    0           10042       10042       20084       10042
    19    0           10042       10042       30126       40168
    20    20084       20084       20084       70294       70294
    21    30126       40168       40168       140588      140588
    22    60252       70294       80336       291218      281176
    23    120504      140588      180756      572394      612562
    24    241008      281176      361512      1144788     1215082
    25    482016      572394      723024      2289576     2420122
    26    953990      1134746     1456090     4538984     4830202
    27    1907980     2259450     2982474     9118136     9660404
    28    3805918     4508858     5804276     18336692    19581900
    
        3
  •  1
  •   IdontCareAboutReputationPoints    9 年前

    我对这两个词做了一个快速而肮脏的比较 CNG managed 在使用下面代码的所有SHA算法中,最慢的是SHA512。

        static void Main(string[] args)
        {
          int loops = 10000000;
          var data = Encoding.ASCII.GetBytes("123");
    
          var hashLoop = new Action<HashAlgorithm>((HashAlgorithm ha) =>
          {
            for (int i = 0; i < loops; i++)
              ha.ComputeHash(data);
          });
    
          var t1 = Task.Factory.StartNew(() =>
          {
            Time(hashLoop, new SHA512Managed());
          });
          var t2 = Task.Factory.StartNew(() =>
          {
            Time(hashLoop, new SHA512Cng());
          });
    
          Task.WaitAll(t1, t2);
          Console.WriteLine("Benchmark done!");
          Console.ReadKey();
        }
        static void Time(Action<HashAlgorithm> action, HashAlgorithm ha)
        {
          var sw = new Stopwatch();
          sw.Start();
          action(ha);
          sw.Stop();
          Console.WriteLine("{1} done in {0}ms", sw.ElapsedMilliseconds, ha.ToString());
        }
    

    经过几次运行后,我发现不同之处在于CNG比算法的管理版本快得多,大约 21.7% to 49.5%

        4
  •  1
  •   Ioanna    7 年前

    托管版本和CNG版本之间的另一个区别是受支持的.Net Framework版本:例如。

    • AES管理版本从3.5开始,而CNG从4.6.2开始,适用于
    • Managed 从1.1和 Cng 从3.5开始。

    压缩天然气版本 :

    • 使用Cng后固定的哈希算法是唯一使用 bcrypt