4

よし、倫理に反することにこれを使用しようとしているように、これは悪く聞こえるだろうが、あなたは私がそうではないという私の言葉を持っている.

私はコンピューターと情報セキュリティのコースで論文を書いていますが、私が選んだトピックはハッシュ方法でした。この論文で取り上げるポイントの 1 つは、MD5 は一方向のみであり、MD5 ハッシュをクラックする唯一の方法は、継続的に文字列を作成し、MD5 関数を使用して、それをクラックしたいハッシュと比較することです。

私は自分の論文と一緒に表示する非常に単純なモックアップ プログラムを作成したいと考えています (私たちはプレゼンテーションを行いますが、これは素晴らしいことです)。そのため、考えられるすべての文字の組み合わせで文字列を作成するアルゴリズムを考え出したかったのです。 8文字まで。たとえば、出力は次のようになります。

a、b、c、...、aa、ab、ac、... ba、bb、bcなどなど

可能であれば、文字、数字、記号を含める必要があります。

このためのアルゴリズムの一部は理解できましたが、残念ながら私のプログラミング スキルでは十分ではありません。誰かがこれのための完全なアルゴリズムを提供できるなら、私は非常に感謝しています.

繰り返しますが、私が嘘つきで、これをハッキング目的で使用するつもりなら、回答を残す必要はありません。

ありがとうございました。:)

4

5 に答える 5

6

Pythonでは、itertools.productは必要なほとんどすべてを実行しますが、1回の「繰り返し回数」で実行するため、1から8まで反復する必要があります(難しいことではありません;-)。本質的に:

import itertools
import string

# whatever you wish as alphabet (lower/upper, digits, punct, &c)
myalphabet = string.ascii_lowercase + string.ascii_digits

def prods(maxlen, alphabet=myalphabet):
  for i in range(1, maxlen+1):
    for s in itertools.product(alphabet, repeat=i):
      yield ''.join(s)

もちろん、長さがNとKの繰り返し(あなたの場合は8)のアルファベットの場合、これはN + N ^ 2 + ... + N ^ Kの可能性(N=36とK=8の場合は2,901,713,047,668の可能性)を生成しますが、友達の間で数兆の出力は何ですか!-)

于 2009-11-01T04:18:04.257 に答える
3

これを実装するには、おそらく整数を base 36 (シンボルが必要な場合はそれ以上) にエンコードします。

1 = 1 2 = 2 ... a = 10 b = 12 ..

等々。

次に、38 のような数を取得し、いくつかの除算を行います。つまり、次のようになります。

38/36 = 1 剰余 2 = 基数 36 の 12

次に、エンコードしたい最大数までforループを実行します。非常に大きなもので、エンコードされた数値を出力します。

楽しみのために私はあなたのためにこれを書きました: http://pastebin.antiyes.com/index.php?id=327

于 2009-11-01T04:01:39.673 に答える
1

「MD5 ハッシュをクラックする唯一の方法」は、考えられるすべての文字列を生成して衝突を探すこ​​とであるというのは正しくありません。実際、元のファイルにアクセスできる場合は、MD5 が作成可能な別のファイルの MD5 と一致するように変更することができます。これについては、infosec.edu の論文で説明されています。

元のファイルを変更できない場合でも、衝突の生成に使用できる MD5 チェックサムのレインボー テーブルが存在します。

これらの事実により、MD5 はパスワードや暗号化には適していません。実際、米国政府は安全なアプリケーションでの MD5 の継続的な使用を禁止しています。

于 2009-11-01T04:10:58.517 に答える
0

0〜9文字とaz文字のみを使用して、Base64でエンコードされたすべての可能な文字の組み合わせのMD5を出力するJavaの例で投稿を完了するには:

MessageDigest digest = MessageDigest.getInstance("MD5");
int i = 0;
while (true)
{
    String raw = Integer.toString(i, Character.MAX_RADIX);
    byte[] md5 = digest.digest(raw.getBytes());
    String base64 = new BigInteger(1, md5).toString(16);
    System.out.println(raw + " = " + base64);
    i++;
}
于 2009-11-01T05:09:43.357 に答える
0

ハッシュ化されたバージョンのパスワードにすでにアクセスできる場合、MD5は最初から壊れています。とは言うものの、ハッシュ値を破るということになると、ブルートフォース方式よりもレインボーテーブル辞書攻撃ソーシャルエンジニアリングを使用したほうがよいでしょう。とはいえ、すべての値を生成するアルゴリズムを要求したので、おそらく次のことが有益です(C#):

using System;
using System.Text;

namespace PossibiltyIterator
{
  class Program
  {
    static readonly char[] Symbols = {
      'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 
      'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 
      'I', 'J', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 
      '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '!', '@', '#', '$', '%', '^', '&', 
      '*', '(', ')', '-', '_', '+', '=', '/', '\\', '[', ']', '{', '}', ';', ':', '\'', '"', 
      ',', '.', '<', '>', '?', '`', '~'
    };

    const int MaxLength = 8;

    static void BuildWord(int currentLength, int desiredLength, char[] word)
    {
      if (currentLength == desiredLength)
      {
        Console.WriteLine(word);
      }
      else
      {
        for (int value = 0; value < Symbols.Length; ++value)
        {
          word[currentLength] = Symbols[value];
          BuildWord(currentLength + 1, desiredLength, word);
        }
      }
    }

    static void Main(String[] args)
    {
      double totalValues = (Math.Pow(Symbols.Length, MaxLength + 1) - Symbols.Length)/(Symbols.Length - 1);
      Console.WriteLine("Warning! You are about to print: {0} values", totalValues);
      Console.WriteLine("Press any key to continue...");
      Console.ReadKey(true /* intercept */);

      for (int desiredLength = 1; desiredLength <= MaxLength; ++desiredLength)
      {
        BuildWord(0 /* currentLength */, desiredLength, new char[MaxLength]);
      }
    }

  }
}

完全に正直に言うと、これはさらに最適化できます。長さ1のすべての「単語」を作成するため、長さ2の単語を作成する際に2回目の作業を行います。長さMaxLengthの単語を作成してから、1文字を切り捨ててMaxLengthの単語を作成する方が賢明です。 1.1。

これが最適化されたバージョンです...最初に要求された順序で単語を返さないことに注意してください。

using System;
using System.Text;

namespace PossibiltyIterator
{
  class Program
  {
    static readonly char[] Symbols = {
      'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 
      'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 
      'I', 'J', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 
      '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '!', '@', '#', '$', '%', '^', '&', 
      '*', '(', ')', '-', '_', '+', '=', '/', '\\', '[', ']', '{', '}', ';', ':', '\'', '"', 
      ',', '.', '<', '>', '?', '`', '~'
    };

    const int MaxLength = 8;

    static void BuildWord(int currentLength, int desiredLength, char[] word)
    {
      if (currentLength != desiredLength)
      {
        for (int value = 0; value < Symbols.Length; ++value)
        {
          word[currentLength] = Symbols[value];
          BuildWord(currentLength + 1, desiredLength, word);
        }
        word[currentLength] = '\0';
      }

      Console.WriteLine(word);
    }

    static void Main(String[] args)
    {
      double totalValues = (Math.Pow(Symbols.Length, MaxLength + 1) - Symbols.Length)/(Symbols.Length - 1);
      char[] word = new char[MaxLength];

      Console.WriteLine("Warning! You are about to print: {0} values", totalValues);
      Console.WriteLine("Press any key to continue...");
      Console.ReadKey(true /* intercept */);

      BuildWord(0 /* currentLength */, MaxLength, new char[MaxLength]);
    }

  }
}
于 2009-11-01T04:38:35.540 に答える