В чем разница между использованием MD5.Create и MD5CryptoServiceProvider? - PullRequest
37 голосов
/ 08 апреля 2010

В фреймворке .NET есть несколько способов вычислить хеш MD5, как мне кажется, однако есть кое-что, чего я не понимаю;

В чем разница между следующим? Что отличает их друг от друга? Кажется, они дают одинаковые результаты:

    public static string GetMD5Hash(string str)
    {
        MD5CryptoServiceProvider md5 = new MD5CryptoServiceProvider();
        byte[] bytes = ASCIIEncoding.Default.GetBytes(str);
        byte[] encoded = md5.ComputeHash(bytes);

        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < encoded.Length; i++)
            sb.Append(encoded[i].ToString("x2"));

        return sb.ToString();
    }

    public static string GetMD5Hash2(string str)
    {
        System.Security.Cryptography.MD5 md5 = System.Security.Cryptography.MD5.Create();
        byte[] bytes = Encoding.Default.GetBytes(str);
        byte[] encoded = md5.ComputeHash(bytes);

        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < encoded.Length; i++)
            sb.Append(encoded[i].ToString("x2"));

        return sb.ToString();
    }

Ответы [ 4 ]

31 голосов
/ 08 апреля 2010

System.Security.Cryptography.MD5.Create () фактически создает MD5CryptoServiceProvider.Вот почему вы видите те же результаты.

Глядя на определение MD5 - это базовый класс и он абстрактный.Я предполагаю, что они добавили публичную функцию создания для простоты использования.

public sealed class MD5CryptoServiceProvider : MD5

public abstract class MD5 : HashAlgorithm

Взгляните на определения.

MD5 Представляет абстрактный класс, из которогоВсе реализации алгоритма хеширования MD5 наследуются.

MD5CryptoServiceProvider Вычисляет значение хеш-функции MD5 для входных данных, используя реализацию, предоставленную поставщиком криптографических услуг (CSP).Этот класс не может быть унаследован.

10 голосов
/ 08 апреля 2010

Как упоминал Джейсон Роу (пожалуйста, проголосуйте за его ответ, это всего лишь предупреждение), функциональной разницы нет.Однако есть разница, если вы рассматриваете MD5Managed (или любой класс криптографии с Managed в имени).Managed Именованные классы нельзя использовать, когда FIPS-совместимые алгоритмы шифрования включены через групповую политику.

2 голосов
/ 13 марта 2017

Мои 2 цента.

MD5 добавляет немного накладных расходов и медленнее по сравнению с MD5CryptoServiceProvider

Я только что провел небольшой стресс-тест, генерирующий 300kхеши строки:

MD5CryptoServiceProvider: 00:00:01.1750834
MD5: 00:00:01.6398959

Почти в 1,5 раза медленнее.

PS.Протестировано на ноутбуке с ядром i7

1 голос
/ 22 марта 2019

Вы также можете создать объект MD5CryptoServiceProvider одним из следующих способов:
(MD5CryptoServiceProvider) HashAlgorithm.Create ("MD5");
(MD5CryptoServiceProvider) HashAlgorithm.Create ("System.SD.Curity.").;

Все классы MD5 возвращают одинаковые хэши, потому что MD5 является стандартным алгоритмом, а не потому, что их код одинаков.

Но способ создания объекта MD5CryptoServiceProvider - не единственный выбор.

На компьютерах правительства США, работающих под управлением Windows, должен быть включен режим FIPS.Этот режим гарантирует, что используемый криптографический код проверен NIST.

Различные криптографические классы .NET обычно существуют в нескольких версиях.Одна версия использует чистый код .NET, в то время как другие вызывают криптографическую функцию Win32 API.

Различные криптографические API-интерфейсы Win32:

  • Криптографический API-интерфейс Windows NT 4: CAPI ( CryptoAPI ).Насколько я понимаю, CSP ( поставщик криптографических услуг ) - это криптографический API над CryptoAPI.
  • API-интерфейс шифрования Windows Vista: CNG (криптография следующего поколения)

Microsoft заявляет, что поставщик криптографических услуг устарел и может быть удален в будущих версиях Windows, и говорит CNGявляется долгосрочной заменой CryptoAPI.

Имена криптографических классов .NET обычно имеют следующие суффиксы:

  • " CryptoServiceProvider " для классов, которые вызывают CryptoAPI Win32 API.
  • " Cng " для классов, вызывающих CNG Win32 API.
  • " Managed " для классов чистого кода .NET.

Некоторые Win32 API могут быть несовместимы с FIPS, и кажется, что по неизвестной причине Microsoft не запрашивала или не могла получить проверку FIPS для криптографического чистого кода .NET.

Классы, которые не соответствуют FIPS, вызывают исключение CryptographicException на компьютерах, на которых включен режим FIPS.Это упоминается в их документации.

Итак, если ваша программа не предназначена для запуска на ПК правительства США, вы можете использовать самый быстрый класс.

Что касается MD5, как предполагают имена классов, класс MD5CryptoServiceProvider должен вызывать очень старый и устаревший CryptoAPI и соответствовать FIPS, в то время как класс MD5Cng вызывает API CNG и не соответствует FIPS.Это показывает, что MD5 может не использоваться на компьютерах правительства США в будущих версиях Windows.Фактически, в документации классов MD5 .NET рекомендуется заменить MD5 на SHA256 или SHA512.

Подробнее о неоднозначной позиции Microsoft в отношении FIPS см.:
https://blogs.technet.microsoft.com/secguide/2014/04/07/why-were-not-recommending-fips-mode-anymore/

MD5CryptoServiceProvider существует из .NET Framework 1.1.Класс MD5CryptoServiceProvider был добавлен во время Windows XP.В то время базовый Win32 CNG API не существовал.Таким образом, метод MD5.Create не имел выбора алгоритма, и Microsoft, вероятно, еще не планировала внедрять CNG в Windows.MD5Cng существует с .NET Framework 3.5, после добавления CNG в Vista.

Приблизительное время выполнения по сравнению с MD5CryptoServiceProvider (чем ниже, тем лучше):
MD5Cng: x 1,08 (.NET Framework 3.5)
SHA256CryptoServiceProvider: x 2,5 (.NET Framework 3.5)
SHA256Cng: x2.4 (.NET Framework 3.5)
SHA256Managed: x 4.8 (.NET Framework 1.1)

Эти неожиданные результаты показывают, что реализация чистого кода SHA256Managed .NET медленнее.
В то время, когда SHA256Managed была реализована, тем лучшеВыполнение Windows Vista CNG не существовало.

Выполнение всегда немного быстрее при выполнении в потоке, чем в байтовом массиве.

Хеш для этого поста, чтобы убедиться, что он не был изменен сторонним агентом:
1c84TiredWithMSDNwrittenByAncientEgyptians4cfebef40b0ae0a906b97c7

...