2010-12-02 7 views
2

ベンダーの要求により、フィールド内に格納できる可変長文字列に基づいてハッシュ値を生成する必要があります。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バイト)です。 ASCIIにエンコードされたときにハッシュ値が、16個のASCI文字に収まるよう、解決策はいくつかを選択するように、

  • 最初のものである必要があることをコメントに基づいて

    --EDIT--

    SHA-256、SHA-384、およびSHA-512を含むSHA-2ファミリの暗号化ハッシュ関数

  • 次に、選択したハッシュ関数の出力を96ビット(12バイト)に切り捨てる - つまり、ハッシュ関数出力の最初の12バイトと残りのバイトを破棄する
  • この場合、切り捨てられた出力を16個のASCII文字(128ビット)に基数64でエンコードします。
  • 効果的に96ビットの強力な暗号化ハッシュを生成します。
+0

16バイトは16進数に変換されたままですが、32文字です。計算されたハッシュの一部を切り捨てることについてのあなたの主張を裏付けるリンクを提供して、より低いバージョンのハッシュを使用するように安全ですか?これはSHA(どちらの方法もわからない)でも当てはまるかもしれませんが、私はあなたがすべてのハッシュで真実である声明を出すことはできないと思います。 –

+0

@Matthew Whited:@ Justiceの主張は、一般的に真実だと思う。切り捨てられたハッシュでは動作しますが、完全なハッシュではなく、ブルートフォースで動作する攻撃を想像するのは難しいです。 –

+0

あなたは単純にハッシュバイトを一連のバイトとして格納することはできないと言っていますか? 16進数のエンコーディングやbase64のエンコーディングなど、バイトをエンコードする必要がありますか?生のバイトを格納できる場合は、生のバイトを格納し、すべての16バイト分の領域を占有する必要があります。 – yfeldblum

0

128ビットの数値を格納する16バイトの場合は問題ありません。 16バイトの値を16進数で格納した32文字の文字列の代わりに、16ビットの値として128ビットの値を格納します。

メモとして、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ビットの4ビット(16進)値で表示されます。ただし、標準のcharは8ビットです。したがって、16文字はMD5ハッシュの値を格納するのに十分です。それを変換するに

、以下を試してみてください。

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バイト以下の数字をシフトしているので、下位ビットと上位ビットは決して衝突しません。 –

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」になります。 Blake2のデフォルト値は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. 
     */ 

これが役に立ちます。