У меня неправильные значения хеша? C # Криптография - PullRequest
1 голос
/ 08 марта 2009

Мой текстовый файл говорит, что быстрая коричневая лиса перепрыгивает через ленивую собаку, однако, когда я пытаюсь получить хэш из этого файла, md5 и sha1 отличаются от результата википедии. У меня есть 3 вопроса. 1) Что я сделал не так в коде? 2) Как я могу получить этот кусок кода лучше? (мне нужно инициализировать) 3) Как мне солить это?

    {
        const int bufSize = 1024 * 8;
        int read;
        byte[] buf = new byte[bufSize];
        string fn = @"b.txt";
        byte[] result1 = new byte[0];
        byte[] result2 = new byte[0];
        SHA1 sha = new SHA1CryptoServiceProvider();
        MD5  md5 = new MD5CryptoServiceProvider();
        sha.Initialize();
        md5.Initialize();
        FileStream fin = File.OpenRead(fn);
        while ((read = fin.Read(buf, 0, buf.Length)) != 0)
        {
            result1 = sha.ComputeHash(buf);
            result2 = md5.ComputeHash(buf);
        }
        fin.Close();
        MessageBox.Show(myFunc(result1));
        MessageBox.Show(myFunc(result2));
    }

Ответы [ 2 ]

6 голосов
/ 08 марта 2009

(РЕДАКТИРОВАТЬ: Утилизация алгоритмов хеширования сейчас. Я подозреваю, что это не нужно, но это хорошая практика:)

Вы вызываете ComputeHash для целого буфера, даже если вы должны хэшировать только часть буфера, которую вы прочитали. Кроме того, вы вычисляете новый хэш для каждого вызова Read.

Вот действительно простой код для вычисления хэшей:

using System;
using System.IO;
using System.Security.Cryptography;

class Test
{
    static void Main()
    {
        byte[] plaintext = File.ReadAllBytes("b.txt");
        using (MD5 md5 = MD5.Create())
        {
            byte[] md5Hash = md5.ComputeHash(plaintext);
            Console.WriteLine(BitConverter.ToString(md5Hash));
        }

        using (SHA1 sha1 = SHA1.Create())
        {
            byte[] sha1Hash = sha1.ComputeHash(plaintext);
            Console.WriteLine(BitConverter.ToString(sha1Hash));
        }
    }
}

Это дает результаты согласно википедии - обратите внимание, что b.txt не должно иметь перевод строки в конце.

Альтернативный способ начать с двоичных данных:

byte[] plaintext = Encoding.ASCII.GetBytes(
    "The quick brown fox jumps over the lazy dog");

Обратите внимание, что это простой способ вычисления хэша за один раз. Если вы хотите сделать это в потоковом режиме (то есть, когда вы читаете некоторые данные, добавляете их в хеш, читаете еще некоторые данные и т. Д.), То вы можете использовать перегрузку ComputeHash(Stream) или (если вы хотите «протолкнуть» данные к нему) вы можете использовать TransformBlock и TransformFinalBlock, например:

using System.Text;

class Test
{
    static void Main()
    {
        using (MD5 md5 = MD5.Create())
        using (SHA1 sha1 = SHA1.Create())
        using (Stream input = File.OpenRead("b.txt"))
        {
            // Artificially small to make sure there's
            // more than one read
            byte[] buffer = new byte[4];
            int bytesRead;

            while ((bytesRead = input.Read(buffer, 0, buffer.Length)) > 0)
            {
                md5.TransformBlock(buffer, 0, bytesRead, null, 0);
                sha1.TransformBlock(buffer, 0, bytesRead, null, 0);
            }
            md5.TransformFinalBlock(buffer, 0, 0);
            sha1.TransformFinalBlock(buffer, 0, 0);

            Console.WriteLine(BitConverter.ToString(md5.Hash));
            Console.WriteLine(BitConverter.ToString(sha1.Hash));
        }
    }
}

Обратите внимание, как мы передаем null в TransformBlock, потому что нам не нужен вывод, и мы не преобразуем никаких данных в последний блок. Я подозреваю, что это пример, который вы захотите использовать, основываясь на ваших предыдущих комментариях.

0 голосов
/ 08 марта 2009

Что касается разных результатов, это может зависеть от кодировки символов, которую вы используете в своем тексте, поскольку эти алгоритмы хеширования имеют дело с байтами.

Что касается улучшения вашего кода, вы не утилизируете своих CryptoServiceProviders. Все, что наследуется от HashAlgorithm , реализует IDisposable и должно быть удалено, когда вы закончите с ним, либо используя using () или вызывая Dispose () напрямую. Вы также не утилизируете FileStream, который предъявляет те же требования к IDisposable.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...