2009-03-08 3 views
1

내 텍스트 파일이 게으른 개를 통해 빠른 갈색 여우가 점프하지만이 파일에서 해시를 얻으려고하면 md5와 sha1이 모두 위키 백과 결과와 다릅니다. 나는 3 개의 질문이있다. 1) 코드에서 내가 뭘 잘못 했습니까? 2) 어떻게이 코드를 더 잘 만들 수 있습니까? (내가 초기화가 필요합니까) 3) 어떻게 이것을 소금합니까?잘못된 해시 값이 있습니까? C# 암호

{ 
     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)); 
    } 

답변

6

(편집 :. 이제 해시 알고리즘 폐기 나는 그것이 불필요 의심하지만 좋은 방법 :

당신은 당신 만의 부분을 해싱한다하더라도 전체 버퍼 ComputeHash를 호출하는 것입니다 읽은 버퍼. 또한 읽기 호출마다 새 해시를 계산합니다.

여기 해시를 계산하기 위해 몇 가지 정말 간단한 코드입니다 :

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) 오버로드를 사용하거나 (데이터를 "밀어 넣기"를 원할 경우))이 같은 TransformBlockTransformFinalBlock, 사용할 수 있습니다

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)); 
     } 
    } 
} 

주 우리가 어떤 출력을 필요로하지 않으며, 우리가 마지막 블록에 데이터를 변환하지 않기 때문에 우리가 TransformBlocknull를 전달하는 방법. 나는 이것이 당신이 이전에 언급 한 것을 토대로 사용하고자하는 예라고 생각합니다.

+0

스트리밍 방식으로 읽을 필요가 있습니다. 홀수 인 경우 내 파일이 여러 GB가 될 수 있기 때문입니다. 위키 피 디아에서 같은 해시를 언급했는지 여부를 확인하는 것이 전적으로 예제입니다. 스트리밍 부분이 어렵다. ComputeHash가 현재 해시 값을 알려주지 못하는 것 같습니다. –

+0

@acidzombie : 편집을 참조하십시오. - 내가 준 두 번째 예제가 필요하다고 생각합니다. –

+0

완벽하고 완벽합니다. 환상적입니다. 감사합니다. D –

0

다른 해시 알고리즘은 바이트를 처리하기 때문에 텍스트에서 사용하는 문자 인코딩에 따라 달라질 수 있습니다.

코드를 개선하는만큼 CryptoServiceProviders를 처분하지 않습니다. HashAlgorithm에서 상속하는 모든 것은 IDisposable을 구현하며 완료 할 때 using()을 사용하거나 Dispose()을 직접 호출하여 처리해야합니다. 또한 IDisposable과 관련된 요구 사항이있는 FileStream을 폐기하지 않아도됩니다.

+0

모든 문자 인코딩 (적어도 Lating 알파벳을 처리하는 모든 문자)은 "단순한 여우가 게으른 개로 점프합니다"라는 문자열을 동일한 바이트 세트로 매핑합니다.이 문자는 단순한 ASCII 텍스트이기 때문에 마찬가지입니다. –

+1

@David : Encoding.Unicode.GetBytes ("빠른 여우는 게으른 개로 점프합니다.") 또는 Encoding.UTF32.GetBytes()를 사용해보십시오. –

관련 문제