2010-12-02 2 views
2

필자는 (공급 업체 요구 사항으로 인해) 16보다 길지 않은 필드 내에 저장할 수있는 가변 길이 문자열을 기반으로 해시 값을 생성해야합니다.C#에서 64 비트의 해시 크기를 생성하는 해시 알고리즘이 있습니까?

해시를 계산하기 위해 C# 스크립트 변환을 통해 전달되는 여러 문자열을 연결합니다. 나는 해시의 출력이 16보다 길 수 없다는 점에서 공급 업체의 파일 사양에 의해 제약을받습니다.

누구에게 의견이 있습니까? 예를 들어, MD5 알고리즘의 문자열 변환은 길이가 32입니다.

+2

16 무엇입니까? 바이너리 또는 텍스트입니까? –

+0

플랫 파일에 기록되므로 이상적으로 텍스트입니다. – Matt

+2

플랫 파일은 텍스트 일 ​​필요는 없습니다. –

답변

5

암호화 기능은 출력을 일부 크기로 자르고 잘린 해시 기능이 안전한 암호화 해시 기능을 유지하도록 설계되었습니다. 예를 들어, SHA-512 출력의 첫 번째 128 비트 (16 바이트)를 일부 입력에 적용한 경우 처음 128 비트는 다른 128 비트 암호화 해시만큼 강력한 암호화 해시입니다.

해결 방법은 SHA-256, SHA-384 및 SHA-512와 같은 128 비트 (16 바이트)의 암호화 해시 함수를 선택하는 것이고, truncate the output은 128 비트 (16 바이트)입니다. 16 개 ASCI 문자에 맞 ASCII로 인코딩 할 때 해시 값이해야합니다,이 솔루션은

  • 처음이라는 의견을 바탕으로

    --EDIT--

    일부를 선택 암호화 해시 함수 (SHA-256 계열, SHA-384 및 SHA-512 계열 포함)

  • 그런 다음 선택한 해시 함수의 출력을 96 비트 (12 바이트)로 자르는 - 즉, 해쉬 함수 출력의 처음 12 바이트와 나머지 바이트를 버린다.
  • 그런 다음 잘린 출력을 16 ASCII 문자 (128 비트)로 base-64 인코딩합니다.
  • 효과적으로 96 비트의 강력한 암호화 해시를 생성합니다.
+0

16 진수로 변환 된 16 바이트는 여전히 32 자입니다. 계산 된 해시의 일부를 잘라내는 것에 대한 귀하의 주장을 뒷받침하는 링크를 제공하여 해쉬의 하위 버전을 사용하는 것이 안전할까요? SHA (이것은 어느 쪽인지는 모르겠다)에게는 사실일지도 모르지만 모든 해시에서 진실을 선포 할 수 있다고 생각하지는 않습니다. –

+0

@Matthew Whited : @ Justice의 주장은 일반적으로 진실이라고 생각합니다. 잘라내 진 해시에서는 작동하지만 전체 해시에서는 작동하지 않는 공격을 상상하기 란 어렵습니다. –

+0

해시 바이트를 단순히 바이트 시퀀스로 저장할 수 없다는 말입니까? 16 진수 인코딩 또는 base64 인코딩과 같이 바이트를 인코딩해야합니까? 원시 바이트를 저장할 수 있으면 원시 바이트를 저장하고 16 바이트 분량의 공간을 모두 차지해야합니다. – yfeldblum

0

128 비트 숫자를 저장하는 16 바이트가있는 경우 문제가되지 않습니다. 128 비트 값을 16 바이트 값을 16 진수로 저장 한 32 자 문자열 대신 16 바이트 값으로 저장하십시오.

MD5 해시를 저장하기 위해 데이터베이스에서 GUID/UUID 필드를 사용했습니다. 더 이상 안전한 암호화하는 동안, 128 비트 MD5 해시는 체크섬을 위해 괜찮 (64 비트보다 훨씬 낫다.) 내가 파일 내용을 표시하지 않습니다

var result = MD5.Create().ComputeHash(new byte[] { 0 }); 

Console.WriteLine(result.Length); 
Console.WriteLine(Convert.ToBase64String(result)); 
Console.WriteLine(result.Aggregate(new StringBuilder(), 
            (sb, v) => sb.Append(v.ToString("x2")))); 

//16 
//k7iFrf4NoInN9jSQT9WfcQ== 
//93b885adfe0da089cdf634904fd59f71 

File.WriteAllBytes("tempfile.dat", result); 

var input = File.ReadAllBytes("tempfile.dat"); 

Console.WriteLine(input.Length); 
Console.WriteLine(Convert.ToBase64String(input)); 
Console.WriteLine(input.Aggregate(new StringBuilder(), 
            (sb, v) => sb.Append(v.ToString("x2")))); 

//16 
//k7iFrf4NoInN9jSQT9WfcQ== 
//93b885adfe0da089cdf634904fd59f71 

참고가 포함됩니다 좋은 기회가 있기 때문에 "인쇄 할 수없는"문자.

0

MD5 해시를 쉽게 사용할 수 있지만 저장 방법을 변경해야합니다. MD5는 128 비트이며 일반적으로 32 비트 (16 진수) 값으로 표시됩니다. 그러나 표준 char는 8 비트이지만 MD5 해시 값을 저장할 수있는 문자는 16 문자입니다. 이 코드에 대한

String hash32 = "d41d8cd98f00b204e9800998ecf8427e" 
String hash16 = "" 

for(int i = 0; i < 32; i+=2) 
{ 
    uint high = Convert.ToUInt32(hash32[i], 16); 
    uint low = Convert.ToUInt32(hash32[i+1], 16); 
    char c = (char) ((high << 4) | low); 

    hash16 += c; 
} 
+0

OR, XOR 또는 다른 이진 함수를 사용하면 다음과 같이 해시 된 해시를 쉽게 해독 할 수 있습니다. 충돌 가능성을 높입니다. 이 값을 사용하여 체크섬을 계산할 수는 있지만 XOR을 사용하면 안전 할 수 있습니다. 그렇지 않으면 패리티 체크를 사용할 수도 있습니다. –

+3

알아두면 항상 4 바이트 이하의 숫자가 왼쪽 4 바이트만큼 이동하므로 하위 비트와 상위 비트가 충돌하지 않습니다. –

0

대한 의견 : 변환 할

다음을 시도? 잘 작동하는 것 같은데 ...

var p = new MD5CryptoServiceProvider(); 
var dic = new Dictionary<long, string>(); 

for (var i = 0; i < 10000000; i++) 
{ 
    if (i%25000 == 0) 
     Console.WriteLine("{0:n0}", i); 

    var h = p.ComputeHash(Encoding.UTF8.GetBytes(Guid.NewGuid().ToString())); 
    var b = BitConverter.ToInt64(h, 0); 

    // "b" is hashed Int64 

    if (!dic.ContainsKey(b)) 
     dic.Add(i, null); 
    else 
     throw new Exception("Oops!"); 
} 
0

이 질문은 비교적 오래된 것으로 나타났습니다. 그러나 누군가가이 답변을 가치있게 찾을 것이라고 확신합니다.

제 제안은 8 비트에서 512 비트까지 사용할 수있는 Blake2b를 사용하는 것입니다. 키 크기가 사용되지 않으면이 경우 기본값이 "512"로 사용됩니다. Blake2s 기본값은 256 비트입니다.

 // BLAKE2b 
     // using System.Data.HashFunction; 
     // 
     // String message to use. 
     string str = "The quick brown fox jumps over the lazy dog"; 
     // Initialize 
     System.Data.HashFunction.Blake2B Blake2B = new System.Data.HashFunction.Blake2B(); 
     // Get string hash bytes; create 64 bit hash. 
     var HashBytes = Blake2B.ComputeHash(str, 64); 
     // Convert bytes to string and remove the dashes. 
     string hexString = BitConverter.ToString(HashBytes).Replace("-", string.Empty); 
     // Display results. 
     MessageBox.Show(hexString); 
     /* 
     * "The quick brown fox jumps over the lazy dog" produces a hash value of 
     * "A8ADD4BDDDFD93E4877D2746E62817B116364A1FA7BC148D95090BC7333B3673F82401CF7AA2E4CB1ECD90296E3F14CB5413F8ED77BE73045B13914CDCD6A918" 
     * and "2FD0F3FB3BD58455" hash for 64 bits. 
     */ 

희망이 있습니다.

관련 문제